The MASM Forum Archive 2004 to 2012

General Forums => The Workshop => Topic started by: Merrick on February 22, 2005, 06:58:01 PM

Title: Floating point arithmetic and DLLs
Post by: Merrick on February 22, 2005, 06:58:01 PM
Hi,

I'm trying to develop a DLL to perform floating point math operations in order to speed up
a visual basic application. I have had no problem developing a prototype that performs
operations on integers, but I am having difficulty passing floating point numbers properly
between VB and the DLL. Does anyone know of a good book or coding example that
might help me solve this problem?

Thanks,
Merrick
Title: Re: Floating point arithmetic and DLLs
Post by: AeroASM on February 22, 2005, 08:17:56 PM
If you are passing a Single or Long, your DLL must receive a DWORD or REAL4, but if you are passing a Double, your DLL must receive a QWORD or REAL8. Does this help? If this is correct, it may be because VB might store floats differently to integers.

As for books and code examples, I have not seen any.
Title: Re: Floating point arithmetic and DLLs
Post by: Merrick on February 22, 2005, 08:28:28 PM
Hi, thanks for the input. I am passing everything in and (hopefully!) out by reference, rather than values. This seems to work just fine with
integers, as I've said, but I get VERY odd results with floating point numbers. And it's not simply the way in which floating point numbers
are represented, as each time I run the application I get different values back from the same input parameters. As far as I can tell it's probably
BOTH an addressing and structure problem.

Anybody else run into this problem??
Title: Re: Floating point arithmetic and DLLs
Post by: AeroASM on February 22, 2005, 09:36:57 PM
When calling external APIs from VB, you have to use ByVal. (Don't know exactly why)

I think that when you use ByRef, VB does gives the DLL the pointer to the variable rather than the value itself. This is why you get different answers for the same question: the variable just has a different address each time.
Title: Re: Floating point arithmetic and DLLs
Post by: Merrick on February 23, 2005, 05:10:47 AM
AeroASM - It is true that API calls must be made by value - but that's simply because it is the way the API's are written (it's the default C calling convention), and is not the way my DLL is written. As I said, this works perfectly correctly for integers - that couldn't be true if the address were changing every time I called the DLL. Actually, now that I think about it, VB doesn't (nor does C) always use ByVal to pass data to and receive data from the external APIs - that can't work for either VB or C when you are passing arrays - and both use indirect addressing when passing arrays. My eventual goal is to pass arrays, and so have passed all of the data by reference from the beginning know that is how I eventually will have to do it in the end.

To solve the floating point problem, however, I have tried every combination of sending all of the arguments by value and by reference I can come up with (and, of course, modifying the DLL code to reflect that). They all behave differently and incorrectly. It's more than a little frustrating, as I'm sure it's a totally trivial thing I'm overlooking.

Thanks for your input.
Title: Re: Floating point arithmetic and DLLs
Post by: AeroASM on February 23, 2005, 07:59:01 AM
So your DLL deferences the parameters given to it? I think the most likely trivial thing you might have got wrong is the derefencing part. Could you post some code?
Title: Re: Floating point arithmetic and DLLs
Post by: TheoMcC on February 23, 2005, 12:19:15 PM
I agree with AeroASM, I suspect your troubles maybe a simple one, ie, proper de-referencing of passed values. Suggest you post some code examples.

Also, if your trying to return a (Single or Double) FUNCTION value, the return value must be left on the x87 stack, specifically, in ST(0). Visual Basic will then take the value from the x87 and return the value to your variable.
Title: Re: Floating point arithmetic and DLLs
Post by: AeroASM on February 23, 2005, 01:55:37 PM
I never knew that; how did you find out?
Title: Re: Floating point arithmetic and DLLs
Post by: MichaelW on February 23, 2005, 04:01:10 PM
If you pass a double from VB to the DLL, VB may pass it on the stack with the upper dword pushed onto the stack first. I have seen CRTL functions that expect this, but I don't recall testing VB. And at least for the CRTL, leaving the result on the FPU stack is the normal method of returning a floating-point value.
Title: Re: Floating point arithmetic and DLLs
Post by: Merrick on February 23, 2005, 04:16:28 PM
Hi all,

Thanks for your input - yes, I think that a large part of my problem is in dereferencing. I'm at work right now, and this project is not an "officially funded" project for work, so I am working on it in my off time. I'll put some code that works for integers (not using the FPU) and some code that doesn't work for floating points (using the FPU) as soon as I can.

In the end, I'm not going to want to pop the values off the FPU stack, however, as I intend to send array references to work on (very lage!) lists of numbers in the DLL.

Thanks again,
Merrick
Title: Re: Floating point arithmetic and DLLs
Post by: Merrick on February 24, 2005, 04:28:01 AM
OK. I'll post these separately:

Here is a DLL that does integer math mostly ByRef, but with some ByVal referencing as well. I have three routines: one is a function that leaves the result in AX for retrieval; one is a subroutine that places the answer back into a variable referenced by passed address; and one is a subroutine that passes the address of the first elements of two input arrays and one output array by address and the length of the arrays by value.

The VB declarations:
Private Declare Function Power2Ref Lib "dllMath1" (ByRef int1 As Integer, ByRef int2 As Integer) As Integer
Private Declare Sub Power2Sub Lib "dllMath1" (ByRef int1 As Integer, ByRef int2 As Integer, ByRef int3 As Integer)
Private Declare Sub Power2Loop Lib "dllMath1" (ByVal count As Integer, ByRef int1 As Integer, ByRef int2 As Integer, ByRef int3 As Integer)

The DLL code:
    .386
    .model flat, stdcall
    option casemap :none

    include \masm32\include\windows.inc
    include \masm32\include\kernel32.inc
    includelib \masm32\lib\kernel32.lib

.code

LibMain proc hInstDLL:DWORD, reason:DWORD, unused:DWORD

        .if reason == DLL_PROCESS_ATTACH
            ret
            ; -----------------------------
            ; If error at startup, return 0
            ; System will abort loading DLL
            ; -----------------------------

        .elseif reason == DLL_PROCESS_DETACH

        .elseif reason == DLL_THREAD_ATTACH

        .elseif reason == DLL_THREAD_DETACH
           
        .endif

        ret

LibMain Endp

Power2Ref proc factorRef:DWORD, powerRef:DWORD
   mov ebx, factorRef
   mov ax, word ptr[ebx]
   mov ebx, powerRef
   mov cx, word ptr[ebx]
   shl ax, cl
   ret
Power2Ref    ENDP

Power2Sub proc factorSub:DWORD, powerSub:DWORD, resultSub:DWORD
   mov ebx, factorSub
   mov ax, word ptr[ebx]
   mov ebx, powerSub
   mov cx, word ptr[ebx]
   shl ax, cl
   mov ebx, resultSub
   mov word ptr [ebx],ax
   ret
Power2Sub    ENDP

Power2Loop proc arrayCount:WORD, factorArray:DWORD, powerArray:DWORD, resultArray:DWORD

   mov ax, arrayCount
   shl ax, 1
   jz done
   mov arrayCount, ax
next:
   mov ebx, factorArray
   add bx, arrayCount
   sub bx, 2
   mov ax, word ptr[ebx]
   mov ebx, powerArray
   add bx, arrayCount
   sub bx, 2
   mov cx, word ptr[ebx]
   shl ax, cl
   mov ebx, resultArray
   add bx, arrayCount
   sub bx, 2
   mov word ptr [ebx], ax
   sub arrayCount, 2
   jz done
   loop next
done:
   ret
Power2Loop    ENDP

End LibMain
Title: Re: Floating point arithmetic and DLLs
Post by: Merrick on February 24, 2005, 04:52:42 AM
Here is the code that does the integer division without the FPU. The quotient is in the low byte and the remainder is in the high byte when returned.

The VB declarations:
Private Declare Function DivideRef Lib "dllMath1a" (ByRef int1 As Integer, ByRef int2 As Integer) As Integer
Private Declare Sub DivideSub Lib "dllMath1a" (ByRef int1 As Integer, ByRef int2 As Integer, ByRef int3 As Integer)

The DLL code:
    .386
    .model flat, stdcall
    option casemap :none

    include \masm32\include\windows.inc
    include \masm32\include\kernel32.inc
    includelib \masm32\lib\kernel32.lib

.code

LibMain proc hInstDLL:DWORD, reason:DWORD, unused:DWORD

        .if reason == DLL_PROCESS_ATTACH
            ret
            ; -----------------------------
            ; If error at startup, return 0
            ; System will abort loading DLL
            ; -----------------------------

        .elseif reason == DLL_PROCESS_DETACH

        .elseif reason == DLL_THREAD_ATTACH

        .elseif reason == DLL_THREAD_DETACH
           
        .endif

        ret

LibMain Endp

DivideRef proc factorRef:DWORD, powerRef:DWORD
   mov ebx, factorRef
   mov ax, word ptr[ebx]
   mov ebx, powerRef
   mov cx, word ptr[ebx]
   sub ax, cx
   idiv cl
   ret
DivideRef    ENDP

DivideSub proc factorRef:DWORD, powerRef:DWORD, resultRef:DWORD
   mov ebx, factorRef
   mov ax, word ptr[ebx]
   mov ebx, powerRef
   mov cx, word ptr[ebx]
   sub ax, cx
   idiv cl
   mov ebx, resultRef
   mov word ptr[ebx], ax
   ret
DivideSub    ENDP

End LibMain
Title: Re: Floating point arithmetic and DLLs
Post by: AeroASM on February 24, 2005, 07:46:52 AM
One glaring mistake is that you haven't preserved ebx. Push it at the beginning of each proc and pop it back off at the end, or simply use edx, which doesn't need to be preserved.
Title: Re: Floating point arithmetic and DLLs
Post by: Merrick on February 24, 2005, 05:27:13 PM
AeroASM - thanks for the correction! Sorry I haven't put up the floating point stuff yet. I put those others up late last night, and I realized that I had tried so many different modifications to that code to try to figure out what was going on that I didn't have any idea what version did what - and need to sort that out before posting it (and needed to get to bed last night!). I'll try to put that up tonight and hopefully a similar silly mistake will pop right up!

Thanks again.
Title: Re: Floating point arithmetic and DLLs
Post by: Merrick on February 26, 2005, 07:25:36 PM
OK. Here are some examples using the FPU, some of which work (those which pass the result back on the stack), some of which don't (those which attempt to pop the result into a memory location before returning to VB). The VB declare statements are:

Private Declare Function Divide2 Lib "dllMath5" (ByVal long1 As Long, ByVal long2 As Long) As Double
Private Declare Sub Divide2Sub Lib "dllMath5" (ByVal long1 As Long, ByVal long2 As Long, ByVal double1 As Double)
Private Declare Function Divide2Float1 Lib "dllMath5" (ByVal double1 As Double, ByVal double2 As Double) As Double
Private Declare Sub Divide2Float2 Lib "dllMath5" (ByVal double1 As Double, ByVal double2 As Double, ByVal double3 As Double)

The DLL code is (leaving out the usual stuff):

Divide2 proc numerator:dword, denominator:dword
   finit
   fild numerator
   fild denominator
   ;fsub
   fdiv
   ret
Divide2    ENDP

Divide2Sub proc numerator:dword, denominator:dword, result:real8
   finit
   fild numerator
   fild denominator
   ;fsub
   fdiv st[0], st[1]
   fst result
   ret
Divide2Sub    ENDP

Divide2Float1 proc numerator:real8, denominator:real8
   finit
   fld numerator
   fld denominator
   ;fsub
   fdiv
   ret
Divide2Float1    ENDP

Divide2Float2 proc numerator:real8, denominator:real8, result:real8
   finit
   fld numerator
   fld denominator
   ;fsub
   fdiv st[0], st[1]
   fst result
   ret
Divide2Float2    ENDP

The functions Divide2 and Divide2Float1 work properly, but the commented "fsub" commands are there and commented out because that is the actual calculation I want to do - (a-b)/b - and though thexse functions return the appropriate results when I compile the code without the fsub command, they produce an "Error 16 - Expression too complex" message when I include it.

The subroutines cause no errors, but what ever values is in the variable passed to result remains in that variable upon return from the DLL. I'm confident this is because I need to pass the return variable by address and not by value in order for that to work, but was hoping to get confirmation of that.

Eventually, I hope to have this working via subroutine with indirect addressing as I want to pass two arrays of numbers to the DLL and have the DLL terminate with a third array containing the results.

I'll try to get the code which passes addresses posted before to long.

Thanks in advance for any suggestions.
Title: Re: Floating point arithmetic and DLLs
Post by: raymond on February 27, 2005, 02:03:32 AM
Merrick

My main recommendations when programming the FPU are:
- Fully understand the requirements and results of the instruction used.
- Comment each FPU instruction with the resulting content of each register based on the above knowledge.

I could certainly spoon-feed you with the correct code but you may not learn as fast. Study carefully the description of the fdiv and fsub (with and without operands) instructions in the following tutorial and write down the result of each FPU instruction of your four proc's (including the commented instructions). Then report back your findings. I will then comment further if necessary.

http://www.ray.masmcode.com/tutorial/appen1.htm

Raymond
Title: Re: Floating point arithmetic and DLLs
Post by: Merrick on February 28, 2005, 02:23:34 AM
Hi Raymond,

Thanks. I'll do that and post the results. I should say that I didn't realize I had posted the code with the explicit registers - I tried that code with implied registers (no registers named) and then with what I thought were the appropriate registers to see if that made a difference. I thought I had this right, but will definitely go check your suggestions.

Thanks!
Merrick
Title: Re: Floating point arithmetic and DLLs
Post by: AeroASM on February 28, 2005, 07:09:57 AM
I find it less error-prone and easier to read if you do one fld, then use fadd, fsub etc with one memory operand and then fstp the result back off. Looking at your code, I think you have made several mistakes concerning the FPU stack, which is probably why Raymond told you to look up the FPU instructions.

By the way, Raymond, why does the FPU have a stack in the first place?
Title: Re: Floating point arithmetic and DLLs
Post by: raymond on February 28, 2005, 06:58:40 PM
QuoteBy the way, Raymond, why does the FPU have a stack in the first place?

The word "stack" for the FPU registers should never have been used in the first place. It can only confuse newbies and does not provide the picture of the bottom of that "stack" being connected directly with the top of the same "stack". If you look at my tutorial, I describes it as the compartments of a revolving barrel. There's no revolving barrel either in the FPU either but at least it cannot be confused with anything on the CPU. ::)

It could also have been described as a chest containing 8 drawers where drawers would need to be shuffled downward and bring the bottom one to the top when loading a register and vice versa when popping it. But rotating a barrel seemed to require less energy. :bg

Raymond
Title: Re: Floating point arithmetic and DLLs
Post by: Merrick on March 01, 2005, 01:59:18 AM
Raymond, thanks for your advice. There were more mistakes in my code than should have been because I tried about 10 different things to get it to work before puttting it up and didn't recognize a couple of obvious mistakes I should have caught before putting the final version up. I have the original MASM 6.1 manuals and read the description of how the stack is handled in chapter 6, but misread the example for floating point arithmetic on page 143. It shows two memory locations, each of which is pushed onto the "stack" (I know, bad word!) and then shows an add operation which add the two number and leaves the result in st (st[0]). At least, that's what I *THOUGHT* it said. I didn't notice that after bothering to load the two values onto the stack the next instruction didn't add the two values it'd pushed onto the stack, but added the top stack value back to first memory location. I read that 10 times and read it wrong each time. In my head I assumed they loaded the two memory locations onto the stack so they could operate on them while on the stack (seemed to make sense!) and my eyes refused to see what was actually going on!

Thanks for your help. Here's the final code doing what I wanted - passing two integers by address and a double precision destination location by address also; the second integer is subtracted from the first integer, then the result of the subtraction is divided by the second integer and the double precision result is placed into the double precision destination addressed:

Divide2Ref proc numerator:dword, denominator:dword, result:dword
   finit
   fild dword ptr[numerator]
   fisub dword ptr[denominator]
   fidiv dword ptr [denominator]
   mov edx, result
   fst qword ptr[edx]
   ret
Divide2Ref    ENDP

(Oh yeah! I also forgot that I didn't realize there was a separate FISUB and FIDIV until looking again!)

Thanks for your help.
Merrick
Title: Re: Floating point arithmetic and DLLs
Post by: raymond on March 01, 2005, 03:05:09 AM
QuoteThanks for your help.
Merrick

My pleasure.

A few comments for future consideration if you ever NEED to optimize for speed.

The finit instruction is slow. It should not be included in procedures which may be called often. It should preferably be used before you start a set of computations and want to insure that the FPU is then "clean".

Working with values already on the FPU is always faster than retrieving them from memory. It does take some time to (i) get them from memory and (ii) convert them to the REAL10 format of the FPU registers. For example, in your snippet, the denominator is brought in twice from memory. Using the following would have saved a few clock cycles:


   fild dword ptr[numerator]       ;a
   fild dword ptr[denominator]     ;b    a
   fsub st(1),st                   ;b    (a-b)
   fdiv                            ;(a-b)/b


And then, you should always clean up the FPU registers whenever you don't need the data anymore. The fst qword ptr[edx] should thus have been:

fstp qword ptr[edx]

which would have left all the FPU registers you used within the proc as FREE as when you entered the proc. (In other cases, you may want to leave the result on the FPU for further processing. This is called FPU register management.)

Keep practicing and you will rapidly become an expert FPU programmer.

Raymond
Title: Re: Floating point arithmetic and DLLs
Post by: zooba on March 01, 2005, 06:33:41 AM
And if you have a return variable set in Visual Basic to be a Single or Double, it will expect to find it on the FPU so leave 1 value on there (in ST(0)).

I can only assume that VB pops it off the FPU itself.
Title: Re: Floating point arithmetic and DLLs
Post by: raymond on March 01, 2005, 05:08:54 PM
QuoteI can only assume that VB pops it off the FPU itself.

When you assume something, you risk being wrong half the time

Raymond
Title: Re: Floating point arithmetic and DLLs
Post by: zooba on March 01, 2005, 11:57:12 PM
Haha, very true.

However, there aren't too many options in this case. Passing memory pointers around in VB is an absolute pain and the only other reasonable way I could imagine to pass a floating-point value is into a VB-allocated section of memory which is passed to the function (rather than the function allocating it and passing a pointer back).

There would be documentation somewhere which specifies, no doubt. However, I don't have the time and/or patience to look it up  :wink
Title: Re: Floating point arithmetic and DLLs
Post by: Merrick on March 04, 2005, 04:57:27 PM
zooba... huh?

Maybe I don't understand what you're referring to. That standard convention for VB calls is to pass memory pointers. If you want to pass values and not pointers you have to explicitly use the ByVal option in your declare statements.
Title: Re: Floating point arithmetic and DLLs
Post by: zooba on March 05, 2005, 08:39:00 AM
No, it appears you don't. :wink Don't worry, it took me a while to learn all the ins-and-outs of VB->ASM programming.

I'll use an example. (Note that this code isn't useful :U)

This passes the single ByVal (hence lea eax, dwValue. passing it ByRef would just use a mov) and returns as a function
; Declare Function Times2 Lib "math.dll" (ByVal Value As Single) As Single

Times2 PROC dwValue:DWORD
    lea     eax, dwValue
    fld     DWORD PTR [eax]
    fld     st(0)
    fadd
    ret        ; Leaves the answer on the FPU for VB to deal with
Times2 ENDP


This passes the single ByVal and a solution ByRef. Note that it leaves the FPU clear and has no return value
; Declare Sub Times2 Lib "math.dll" (ByVal Value As Single, ByRef Solution As Single)

Times2 PROC dwValue:DWORD, lpSolution:DWORD
    lea     eax, dwValue
    fld     DWORD PTR [eax]
    fld     st(0)
    fadd
    mov     eax, lpSolution
    fstp    DWORD PTR [eax]
    ret
Times2 ENDP


I haven't discovered any noticable performance difference between the two styles (tested in the VB IDE with GetTickCount and a few million iterations) except I haven't found any guarentee that VB cleans the FPU up properly (and judging from a few random errors I get when using OpenGL, I'd say that it doesn't  ::))

Quote from: zooba on March 01, 2005, 11:57:12 PMPassing memory pointers around in VB is an absolute pain

Just to explain this (which is where I think you may be getting confused), you'd (ie. I would) never dream of returning a pointer as a Long to VB, because it provides no intrinsic functionality for dealing with it (API calls only). It also automatically deals with ByRef statements and treats them as the actual value rather than a pointer as ASM would. To illustrate that last point...

Sub MySub(Value As Long)
    MsgBox Value
End Sub


Sub MySub(ByVal Value As Long)
    MsgBox Value
End Sub


...both display an identical message box. Passing a memory pointer is totally transparent within VB and with most API calls which already include 'ByVal' where appropriate in their declarations. This means that receiving a memory pointer as a return value causes a lot of headaches (for an example which was giving me headaches until I wrote an ASM routine to deal with it, 'glGetString' returns a POINTER to a null-terminated string. VB just sees a Long [DWORD] value and can't recognise that there's a string at the end, and the string is in the wrong format. In ASM, it's trivial to move the address into ESI and just do a string copy until reaching the null character - VB provides no functionality for this)

Whoa, thats quite a lot - one of my longest posts yet. I s'pose I should consider writing a whole essay on this subject, shouldn't I  :8)
Title: Re: Floating point arithmetic and DLLs
Post by: MichaelW on March 05, 2005, 08:43:16 PM
This is a test of passing doubles from VB to a DLL and back to VB using both ByVal and ByRef. As coded (now after I removed a dumbass error :red) both methods work correctly (with VB5CCE, because I'm too lazy to install 6).

; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
      .486                      ; create 32 bit code
      .model flat, stdcall      ; 32 bit memory model
      option casemap :none      ; case sensitive

      include \masm32\include\windows.inc
      include \masm32\include\masm32.inc
      include \masm32\include\kernel32.inc
      includelib \masm32\lib\masm32.lib
      includelib \masm32\lib\kernel32.lib
      include \masm32\macros\macros.asm
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
      .data?
        hInstance dd ?
      .code
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
LibMain proc instance:DWORD,reason:DWORD,unused:DWORD
    .if reason == DLL_PROCESS_ATTACH
      push instance
      pop hInstance
      mov eax, TRUE
    .elseif reason == DLL_PROCESS_DETACH
    .elseif reason == DLL_THREAD_ATTACH
    .elseif reason == DLL_THREAD_DETACH
    .endif
    ret
LibMain endp
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
ReturnDoublePassedByVal proc dbl:QWORD
    LOCAL localdbl:QWORD
    ; Verify high-order dword passed first.
    mov   eax,[ebp+12]
    mov   DWORD PTR localdbl+4,eax
    mov   eax,[ebp+8]
    mov   DWORD PTR localdbl,eax
    fld   localdbl
    ret
ReturnDoublePassedByVal endp

ReturnDoublePassedByRef proc ptrdbl:DWORD
    mov   eax,ptrdbl
    fld   QWORD PTR [eax]
    ret
ReturnDoublePassedByRef endp
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end LibMain

Title: Re: Floating point arithmetic and DLLs
Post by: AeroASM on March 06, 2005, 09:25:38 PM
Zooba,

In your previous example you used:


lea eax,dwValue
fld dword ptr [eax]


Why not just use:


fld dwValue
Title: Re: Floating point arithmetic and DLLs
Post by: zooba on March 07, 2005, 11:06:26 AM
Simply because for some reason I don't trust the assembler to handle it correctly.  :bg

No doubt you can use the other way, but the one extra instruction isn't going to hurt at all.
Title: Re: Floating point arithmetic and DLLs
Post by: AeroASM on March 07, 2005, 11:37:02 AM
I am horrified if I write something superfluous in ASM. I feel that because ASM is the best language to write in in terms of speed, you should always optimise as much as you can. If I don't feel like optimising, I write in VB.  :wink
Title: Re: Floating point arithmetic and DLLs
Post by: Merrick on March 08, 2005, 09:02:37 PM
OK, zooba, maybe I dont get it. Perhaps you can explain it in words...

You say that passing pointers with VB is a pain, then show an example where you apparently do it.
That's exactly the way I do it...

So, is that NOT an example of passing pointers, or what it is so hard about it if it is?
Title: Re: Floating point arithmetic and DLLs
Post by: zooba on March 09, 2005, 02:35:53 AM
Quote from: AeroASM on March 07, 2005, 11:37:02 AMI am horrified if I write something superfluous in ASM. I feel that because ASM is the best language to write in in terms of speed, you should always optimise as much as you can. If I don't feel like optimising, I write in VB.

Maybe, but in any case, simply changing from VB to ASM provides a massive speed increase (ignoring procedure call overhead) because VB is basically an interpreted language. Also, it's not superfluous if it helps you understand it better or it makes it work where another option may not.  :U

Quote from: Merrick on March 08, 2005, 09:02:37 PMYou say that passing pointers with VB is a pain, then show an example where you apparently do it.
That's exactly the way I do it...

The difference is, you can't access the memory pointer. That is, you can't add 4 to it and have it point to the next DWORD. VB simply interacts automatically with the memory at the other end. Unlike other languages, you can't force a Long to act as a pointer and you can't display the actual value of the pointer (without using hidden internal functions, VarPtr or StrPtr). This is what I mean by the ByRef process being transparent. As far as the VB programmer is concerned, it's just a variable. The assembly programmer can recognise that it is an address being passed rather than the actual value, but VB doesn't care - you can't work with it as a memory pointer, it is just the value.
Title: Re: Floating point arithmetic and DLLs
Post by: AeroASM on March 09, 2005, 08:21:58 AM
Quote from: zooba on March 09, 2005, 02:35:53 AM
Quote from: AeroASM on March 07, 2005, 11:37:02 AMI am horrified if I write something superfluous in ASM.
it's not superfluous if it helps you understand it better or it makes it work where another option may not.

But where you wrote it, it made it harder to understand and the shorter option would still work.
Title: Re: Floating point arithmetic and DLLs
Post by: zooba on March 09, 2005, 09:14:06 AM
Quote from: AeroASM on March 09, 2005, 08:21:58 AM
But where you wrote it, it made it harder to understand and the shorter option would still work.

Obviously it made it easier for me or I wouldn't have written it that way...
Title: Re: Floating point arithmetic and DLLs
Post by: AeroASM on March 09, 2005, 11:40:14 AM
But what is simpler?

1. "Put a value on the FPU stack"

2. "Get the address of a value, and then put the contents of that address on the FPU stack"
Title: Re: Floating point arithmetic and DLLs
Post by: Merrick on March 09, 2005, 10:28:24 PM
zooba - thank you. Now I understand what you were talking about. As you say, to work fully within VB with memory pointers you need to use VarPtr, VarPtrArray, etc. - but it won't by you anything. Since I'd started this thread regarding VB and interaction with DLLs, I assumed you were referring to that - not using pointers exclusively within VB.
Title: Re: Floating point arithmetic and DLLs
Post by: zooba on March 09, 2005, 10:44:30 PM
Glad I could help, Merrick. Feel free to contact me if you want any more info on VB with ASM.


Quote from: AeroASM on March 09, 2005, 11:40:14 AM
But what is simpler?

1. "Put a value on the FPU stack"

2. "Get the address of a value, and then put the contents of that address on the FPU stack"

This is a totally fruitless discussion which I refuse to participate any further in.
Title: Re: Floating point arithmetic and DLLs
Post by: Merrick on March 11, 2005, 02:23:07 PM
Maybe this shuold be in a new topic???

The final goal of this DLL is:

I have a 3D array containing 256 images, 200X200 unsigned ints/image (sadly, stored Big Endian) in 128 sets - that is - the first 200X200 array is image information, the second 200X200 array is the background correction information for that image, etc. So, I have one DLL taking the Big Endian array and converting it to a Little Endian array. Then, in a loop in VB, I call the image correction DLL 128 times, passing the starting address of successive data sets to the DLL to be processed one image set at a time. This is pretty straight forward. I intend to put the little/big endian conversion in the same DLL so I can just do one call, but doubt that will save any time (and since I'm making 128 DLL calls for the image processing, so what, right?) What I think WILL save time is if I can process the whole array in one call - which requires nested loops. I tried this a couple of times and had bad results. Can anyone help me track down examples of design with nested loops?

Thanks...