Function call and stacks for Calling Conventions


When a function is called arguments are passed to the called function by different means, like stacks ,registers. Similarly return is either done by stack or register,

According to function calling conventions the compiler design the assembly code from c/cpp codes to pass arguments to called function. It also specify the stack handling of the portion used by the function.
In x86 stack normally grow downward. EBP keeps track of the base of the frame(frame pointer),and ESP keeps track of the top of the stack.EAX have the return value.
In PPC stack pointer is r1,Base pointer is r0,r3 is the return register. As I blogged before on PPC register classification.

(from wikipedia)

The C function Calling convention define following things
  1. Order in which arguments are pushed on the stack.
  2. Who is responsible for stack clean-up process either callee or caller function after call complete.
  3. Name decorating for individual function before linking.
Available call conventions.
Keywords Stack Cleaner Descriptions
__cdecl Caller Pushes arguments to stack in reverse order(right to left).This is default call convention for variable argument calls(e.g. Printf).Increases the overall code size because adds extra code after each call to clean up the stack.
__stdcall Callee Also used as __pascal(but pushed left to right,not available in gcc).Needs function declearation to use this convention. Push arguments on stack on revesrse (right to left).No of arguments fixed. For Win32 it's the default convention.Before existing the function called function clear the stack.
__fastcall Callee Arguments are passed by registers,if possible ,else on stack.called function clean the stack.(2 args max in register others in stack as for GCC and Microsoft fastcall)

Function call conventions declarations vary in different compilers.
Examples:
/* for Borland and Microsoft compilers */
void __cdecl funFoo(int arg1,int arg2)
/* For GNU GCC */
void funFoo(int arg1,int arg2) __attribute__((cdecl))

Now the generated assemblies are as below.
1)/* for __cdecl */
    push arg2
    push arg1
    call funFoo// call the function
    add  esp,8 // sizeof(arg1+arg2) stack clean-up
2)/* for __stdcall */
       push arg2
     push arg1
     call funFoo//In function stack cleanup just before return
/* note : optional 16 byte with “ret” call can be used to unwind the stack too in function instead of using ESP, e.g. Ret 12 ,unwind 12 bytes */

x64 calling convention is little bit different .Check wikipedia and googling.

Two objects compiled with different compiles with same calling convention and not calling any underlying environment may not link because returning from functions may be different.
In general x86 compilers return values on EAX.But some compilers return values in data structure in two registers.(e.g EAX : EDX).For in memory/return on argument type function allocates memory and passes the pointer in stack. Callee use it as another parameter.

Linker Symbol and naming decoration according to calling conventions:
Linker Symbols and naming decoration is a in-between steps cannot be visible unless disassembly. This is only visible to linker (as present in object files)
Keywords Extern “c”or *.c *.cpp,*.cxx Remarks
__cdecl _funcFoo ?funcFoo@@ZAXXZ No number of params,as caller cleans the stack.
__fastcall @funcFoo@N ?funcFoo@@YIXXZ N – number of bytes of params passed to function, 0 if none
__stdcall
_funcFoo@N


?funcFoo@@YGXXZ


N – The number of bytes of parameters passed to function, 0 if void.

Ref.

Comments

Popular posts from this blog

Airtel Digital tv remote factory reset and reprogram

Tracking Linux kworker threads

Asynchronus I/O (AIO) in vxworks and Linux