In the GCC cdecl
calling convention, can I rely on the arguments I pushed onto the stack to be the same after the call has returned? Even when mixing ASM and C and with optimization (-O2
) enabled?
The stdcall calling convention is a variation on the Pascal calling convention in which the callee is responsible for cleaning up the stack, but the parameters are pushed onto the stack in right-to-left order, as in the _cdecl calling convention. Registers EAX, ECX, and EDX are designated for use within the function.
For example, the registers used for the first 6 arguments and return value are all caller-saved. The callee can freely use those registers, overwriting existing values without taking any precautions.
To pass parameters to a subroutine, the calling program pushes them on the stack in the reverse order so that the last parameter to pass is the first one pushed, and the first parameter to pass is the last one pushed. This way the first parameter is on top of the stack and the last one is at the bottom of the stack.
Calling conventions specify how arguments are passed to a function, how return values are passed back out of a function, how the function is called, and how the function manages the stack and its stack frame. In short, the calling convention specifies how a function call in C or C++ is converted into assembly language.
In a word: No.
Consider this code:
__cdecl int foo(int a, int b)
{
a = 5;
b = 6;
return a + b;
}
int main()
{
return foo(1, 2);
}
This produced this asm output (compiled with -O0):
movl $5, 8(%ebp)
movl $6, 12(%ebp)
movl 8(%ebp), %edx
movl 12(%ebp), %eax
addl %edx, %eax
popl %ebp
ret
So it is quite possible for a __cdecl function to stomp on the stack values.
That's not even counting the possibility of inlining or other optimization magic where things may not end up on the stack in the first place.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With