1. Calling Conventions
- Posted by Chris Bensler <bensler at nt.net> Feb 10, 2007
- 466 views
It is my understanding that cdecl functions require the caller to cleanup the stack, whereas the others are required to cleanup the stack themselves? I'm working on some code for the various calling conventions using cprintf() as one of my test functions which is a variadic function and thus is sure to be cdecl. Another function I'm using is GetVersion() from the WINAPI which I'm quite positive is stdcall. The asm I've create seems to work fine except that I had thought that the instruction "add esp, ebx" would have to be removed for stdcalls. Strangely, it works for both cdecl and stdcall if the instruction is present but crashes for both if it isn't. I also thought that popa would restore the stack, meaning that the add esp, ebx instruction was redundant, but the call to GetVerison() doesn't work without it. Matt's fptr.e asm code doesn't do any explicit stack cleanup either. Here is the asm:
constant STDC_ASM = get_asm("" & "pusha " & "mov ecx, ARGC " -- argument count must be in ecx for movsd -- get byte size of array -- ebx = ecx * 4 & "mov ebx, ecx " & "shl ebx, 1 " -- ecx *= 2 -- can't shift by 2, instead of shifting 2x? & "shl ebx, 1 " -- ecx *= 2 & "sub esp, ebx " -- offset stack pointer & "cld " -- clear direction flag & "mov edi, esp " -- movsd dst & "mov esi, ARGV " -- movsd src & "rep movsd " -- poke4 & "call near dword ptr [FUNC] " -- call the function & "add esp, ebx " & "mov ebx, RETV " & "mov [ebx], eax " -- return value & "add ebx, 4 " & "mov [ebx], edx " -- double & "popa " & "ret " )
Chris Bensler ~ The difference between ordinary and extraordinary is that little extra ~ http://empire.iwireweb.com - Empire for Euphoria
2. Re: Calling Conventions
- Posted by Robert Craig <rds at RapidEuphoria.com> Feb 10, 2007
- 473 views
Chris Bensler wrote: > It is my understanding that cdecl functions require the caller to cleanup the > stack, whereas the others are required to cleanup the stack themselves? Yes. > I'm working on some code for the various calling conventions using cprintf() > as one of my test functions which is a variadic function and thus is sure to > be cdecl. Another function I'm using is GetVersion() from the WINAPI which I'm > quite positive is stdcall. > > The asm I've create seems to work fine except that I had thought that the > instruction > "add esp, ebx" would have to be removed for stdcalls. Strangely, it works for > both cdecl and stdcall if the instruction is present but crashes for both if > it isn't. I've found that code compiled by Watcom, such as exw.exe, or translated code compiled by Watcom, is more or less immune to crashing, even if you use the wrong calling convention (cdecl vs. stdcall). I confirmed this once by examining the actual machine code produced by Watcom. I don't remember off-hand exactly what the code sequence was, but it was somehow saving/restoring the stack pointer and avoiding a crash. This appeared to be just luck, not some clever plan. Regards, Rob Craig Rapid Deployment Software http://www.RapidEuphoria.com
3. Re: Calling Conventions
- Posted by Matt Lewis <matthewwalkerlewis at gmail.com> Feb 10, 2007
- 457 views
Chris Bensler wrote: > > Matt's fptr.e asm code doesn't do any explicit stack cleanup either. Actually, it does. For stdcall, I use
#C2,#00,#00,#00,#00} -- 1F: ret [argnum] (#20)
...and in a cdecl call:
#83, #C4, 00, -- 1F: add esp 0
Then I fill in the appropriate value at runtime to clean up the stack. Matt