I'm getting confused.
When I write a function:

int test(int a, int b); // stdcall and cdecl , I found the data order in the stack is the same?

But I think they should be different 'cause stdcall function's parameters is push to the stack from left while cdecl is contrary.
Does it only exist in win32 platform?

Please Help Me! Thanks!



00000000 <_test@8>:
0: 8b 44 24 04 mov 0x4(%esp,1),%eax
4: 2b 44 24 08 sub 0x8(%esp,1),%eax
8: c2 08 00 ret $0x8
b: 90 nop
c: 90 nop
d: 90 nop
e: 90 nop
f: 90 nop
Disassembly of section .text:


00000000 <_test>:
0: 8b 44 24 04 mov 0x4(%esp,1),%eax
4: 2b 44 24 08 sub 0x8(%esp,1),%eax
8: c3 ret
9: 90 nop
a: 90 nop
b: 90 nop
c: 90 nop
d: 90 nop
e: 90 nop
f: 90 nop
Disassembly of section .text:
:confused: :confused: :confused: :confused: :confused: :confused:
Posted on 2003-09-05 08:51:06 by hanzac
Look at the retn. There is 2 types, retn immed8 and just plain ret. The immediate states how many bytes is needed to be cleared from the stack (ie for stdcall), however usually for the plain retn without an immediate is for cdcel which does not require the function to clear the stack, but requires the calling function to clear the stack.

So the main difference between stdcall and cdecl is that who clears the stack. That's all. On win32 platform, the most of the apis are stdcall except for some apis like wprintf.
Posted on 2003-09-05 10:15:53 by roticv
But why someone says stdcall/pascal functions's parameters should push into the stack from right to left?
:rolleyes:
Posted on 2003-09-05 19:33:43 by hanzac
C call would pretty much have to be reverse ordered for those procs which can take a variable no. of args. At least it would be harder if they were forward pushed.
Posted on 2003-09-05 20:21:17 by Eóin
Because STDCALL pushes arguments starting with the rightmost argument.
I know -- I've hard coded this in MASM and TASM.
Posted on 2003-09-05 20:31:13 by tenkey
Is it true?

I defined two functions:

[1]
int stdcall test(int a, int b); // when call this function the code goes such way.
movl $0xd,0x4(%esp,1) // b
movl $0xc,(%esp,1) // a
call 6c <_test@8>
sub $0x8,%esp

[2]
int test(int a, int b); // here it is.
movl $0xd,0x4(%esp,1) // b
movl $0xc,(%esp,1) // a
call 6c <_test>

We can see that the stack-pushing is the same.
and why "sub $0x8, %esp" after stdcall?

I am getting confused.:confused: ( I compiled the code with MingW GCC 3.3.1)
Posted on 2003-09-06 02:18:56 by hanzac
Speaking about calling conventions there is nice link:

Calling Conventions Demystified
Posted on 2003-09-06 02:42:44 by MazeGen
Weird the sub esp, 8 is more like allocating space on the stack rather than clearing the stack. To clear the stack it should be add esp, xx since the stack grows downwards, ie from big to small. Mayhaps the sub esp,8 is part of some other codes.

But why someone says stdcall/pascal functions's parameters should push into the stack from right to left?

It is just the way how parameters are seen. But actually it does not really matter. :) Unless of course you are doing something special.
Posted on 2003-09-06 02:57:11 by roticv

Speaking about calling conventions there is nice link:

Calling Conventions Demystified


Yes, this article is rather good. It gives me a clearer vision. Thanks.
Posted on 2003-09-06 03:40:52 by hanzac

Weird the sub esp, 8 is more like allocating space on the stack rather than clearing the stack. To clear the stack it should be add esp, xx since the stack grows downwards, ie from big to small. Mayhaps the sub esp,8 is part of some other codes.


It is just the way how parameters are seen. But actually it does not really matter. :) Unless of course you are doing something special.


I get the point now: because the stdcall function use "ret imm8", but when gcc use addl xx, xx(%esp, 1) rather than pushl xx.
so it should "sub $0x8,%esp".

But I wonder whether it is compatible when using "addl" instead of using "pushl"?
Posted on 2003-09-06 03:45:53 by hanzac