Hi All,
Could someone explain to me how to return a 64 bit number through a function's return value ( 64bitNumber=GetCPUTimeStamp() ). This little PROC is currently returning the number through one of the procedure parameters, which isn't the cleanest approach. I'm new to this assembler stuff (but at least I'm getting comfortable with it) and don't really understand how the function return value is returned through the stack. I'm betting it will be changing the 'ret 16' to something else, but for me, the question is what to.

ret 16 returns a 32 bit number, not a 16 bit.

Thanks - Jack

The code below is for yet another GetCPU speed function. This little piece just gets the number of cpu cycles and returns it as a LARGE_INTEGER (Currency in Visual Basic).

[size=9] ;Purpose:   Get the CPU Time Stamp and Put results into Long1

; Where Long1 which is a Currency Data Type (LONG_INTEGER)
;vb code -> res& = CallWindowProc(VarPtr(MachCode(1)), VarPtr(Lng1),2&, 3&, 4&)
.586
.model small
.code

GetCPUTimeStamp PROC STDCALL USES ebx ecx edx long1:dword, long2:dword, long3:dword, long4:dword

rdtsc

;put EAX into LowPart of LARGE_INTEGER
mov ebx,long1
mov [ebx],eax

;put EDX into HighPart of LARGE_INTEGER
add ebx,4 ;move addr pointer fordward 4 bytes
mov [ebx],edx


;Finish Up
ret 16
GetCPUTimeStamp endp
END
[/SIZE]
Posted on 2002-03-02 10:35:17 by JackRazz
Pass a pointer to the routine, then store the data at that address - which your doing. Another option is to use C calling convention and pop the value off the stack.
GetCPUTimeStamp PROC C USES ebx ecx edx dummy1:dword, dummy1:dword

rdtsc
mov dummy1,eax
mov dummy2,edx
ret
GetCPUTimeStamp endp

; use it like

invoke GetCPUTimeStamp, 0, 0
pop eax
pop edx
But why not just use RDTSC, returning the value in EAX/EDX - I'm assuming you need this for interfacing with another language?
Posted on 2002-03-02 11:02:32 by bitRAKE
Yea I'm using another language (Visual Basic). Doesn't STDCALL pass back function values thru the stack or does it pass back the address thru the function?

thanks for the reply - jack
Posted on 2002-03-02 12:22:22 by JackRazz
STDCALL corrects the stack based on passed parameters. Apon returning there is nothing left on the stack - that is why you pass an address and modify the memory directly. Usually an error code, er something is returned in EAX.
Posted on 2002-03-02 19:05:38 by bitRAKE
another possibily is that you could split the 64 bit value into eax and ebx and then return. But if you did this you would have to get the returned value using ASM as high level languages pick up the return value from eax only.
Posted on 2002-03-02 21:11:20 by Quantum
You see, this is why we have standards. I think the EDX:EAX standard is pretty nice. Things like GetDiskFreeSpaceEx use it. Even things like DIV agree that a 64-bit number is in EDX:EAX.

Too bad everybody doesn't feel this way...

:grin:

PS - Silly me. GDFSE returns a 64 bit value in memory. I was thinking of my QTOAE function, that passes it in EDX:EAX...

:rolleyes:
Posted on 2002-03-02 21:41:49 by S/390
Just a theory. Push the 64bit value to the FPU stack then pop it off after a procedure. FLD or FILD then FSTP or FISTP. Then again, your using this for VB :(


Use MMX :) -> if this is possible under VB
Posted on 2002-03-02 21:44:06 by stryker
Thanks for the suggestions. I'll just settle with using the argument to pass the results back.

Case Closed :cool: - Jack
Posted on 2002-03-03 19:24:47 by JackRazz
I wonder how VC++ handles returning 64bit values? I think it has
a native 64bit datatype that you can even use in 32bit programs,
but I might be wrong...
Posted on 2002-03-03 19:56:19 by f0dder
There are also floating point types in VB,
but I don't know how they are passed.
If it is on the FPU stack, you could just:

push edx
push eax
fild QWORD PTR
add esp,8
Posted on 2002-03-03 20:01:56 by bitRAKE
I wonder how VC++ handles returning 64bit values? I think it has
a native 64bit datatype that you can even use in 32bit programs,
but I might be wrong...


I recently tried this out as I needed a 64-bit value to count up filesizes (which can get beyond the 32-bit boundary). I used the __int64 datatype, as return value of a procedure. return 0; resulted in 'xor eax, eax', 'xor edx, edx' so it probably uses edx:eax to return a value. I don't know if there's a standard for it though.

Thomas
Posted on 2002-03-04 01:43:01 by Thomas
Thomas, this sounds reasonable, and was one of the two possibilities
I found likely - the other being int64 not being supported as a
return type. edx:eax makes a lot of sense, since that's also what
DIV uses.
Posted on 2002-03-04 10:49:55 by f0dder