1. Calling Conventions

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

new topic     » topic index » view message » categorize

2. Re: Calling Conventions

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

new topic     » goto parent     » topic index » view message » categorize

3. Re: Calling Conventions

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

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu