Anyone can give a simple sample code that is changes a function return value? I can work with subs, but being able to work with functions would be handy as well.
Printable View
Anyone can give a simple sample code that is changes a function return value? I can work with subs, but being able to work with functions would be handy as well.
functions usually return their result in the EAX or EAX:EDX register(s) or somewhere in memory and return a pointer. floating point values are returned in the floating point registers. so what you have to do depends on the function.
can you post a sample code?
Current mess I have:VB Code:
Public Function AsmIfSng(ByVal Expression As Long, ByRef TruePart As Single, ByRef FalsePart As Single) As Single ''#asm'.pureasm '#asm' push ebp '#asm' mov ebp, esp '#asm' push ebx '#asm' push esi '#asm' push edi '#asm' '#asm' mov eax, [ebp+8] '#asm' cmp eax, 0 '#asm' je falsepart '#asm' mov ebx, dword ptr [ebp+12] '#asm' jmp done '#asm' falsepart: '#asm' mov ebx, dword ptr [ebp+16] '#asm' '#asm' done: '#asm' mov ?,? '#asm' pop edi '#asm' pop esi '#asm' pop ebx '#asm' mov esp, ebp '#asm' pop ebp End Function
Basically trying to do this out of interest to see how big difference I there is between native VB6 implementation and an inline ASM version. And to learn atleast some ASM.
the VB code...
VB Code:
Public Function IfSng(ByVal Expression As Long, ByRef TruePart As Single, ByRef FalsePart As Single) As Single If Expression Then IfSng = TruePart Else IfSng = FalsePart End Function
and how it is compiled (assembly listing)
i'm not a assembly guru but i think the VB compiler does a good job here.Code:PUBLIC ?IfSng@modCastedProcs@@AAGXXZ ; modCastedProcs::IfSng
EXTRN __fltused:NEAR
; COMDAT ?IfSng@modCastedProcs@@AAGXXZ
text$1 SEGMENT
_FalsePart$ = 16
_TruePart$ = 12
_Expression$ = 8
?IfSng@modCastedProcs@@AAGXXZ PROC NEAR ; modCastedProcs::IfSng, COMDAT
; 58 : If Expression Then IfSng = TruePart Else IfSng = FalsePart
mov eax, DWORD PTR _Expression$[esp-4]
test eax, eax
je SHORT $L129
mov eax, DWORD PTR _TruePart$[esp-4]
fld DWORD PTR [eax]
; 59 : End Function
ret 12 ; 0000000cH
$L129:
; 58 : If Expression Then IfSng = TruePart Else IfSng = FalsePart
mov ecx, DWORD PTR _FalsePart$[esp-4]
fld DWORD PTR [ecx]
; 59 : End Function
ret 12 ; 0000000cH
?IfSng@modCastedProcs@@AAGXXZ ENDP ; modCastedProcs::IfSng
text$1 ENDS
Ah, thanks :) I ended up with this:Pretty much the same code VB compiles to, but for some reason I found that the ThunderVB/MASM32 compiled version performed slightly faster (0.86 ms vs. 0.8 ms with 100 000 loops). Also, for a reason I do not understand, the first time I call the "native VB" compiled version, it seems to have a big slowdown. But on second test it works just as fast as the ASM version.VB Code:
Public Function AsmIfSng(ByVal Expression As Boolean, ByRef TruePart As Single, ByRef FalsePart As Single) As Single '#asm'.pureasm '#asm' mov eax,[esp+4] '#asm' test eax,eax '#asm' je falsepart '#asm' mov eax,[esp+8] '#asm' fld dword ptr [eax] '#asm' ret 12 '#asm' falsepart: '#asm' mov ecx,[esp+12] '#asm' fld dword ptr [ecx] '#asm' ret 12 End Function
Edit!
Oo, VB6's compiled version is faster for False. End conclusion: VB6 compiler does so good with this that there is no need to optimize :)
unfortunately it doesn't seem to be easy to get proper benchmark results. when you compare two functions then the first one always seems to be slower then the second one. run every test at least twice in a row. and the longer the test runs the more accurate is the result.
the reason why the second test is faster might be that things are already in the second or fist level cache :confused:
I don't test like that: I always put benchmarks behind their own buttons. One button for one test and you can ensure with multiple tries what is the general truth behind there :) I found out that weirdness in my own benchmarkings a few years ago and since then I've always had benchmarked code separated from each other.