Software is developed as a collaborative effort, there has to be some set of standards and protocols defined between the API provider and the API consumer. Calling standards or conventions are the protocol established between caller function and the callee function. Calling standards cover aspects like
Parameter passing
Return values
Register usage
In the first few posts, we already discussed register usages. For example, x86 calling standard states
ESP register should be used as a stack pointer
EBP should be used as a frame pointer
EAX should store the return value of a function
EAX, ECX, EDX – are volatile registers, other general purpose registers are non-volatile
In case of x86-64 - the ABI suggests :
The first four parameters are passed in RCX, RDX, R8 and R9. RAX is used to store the return values.
The registers RAX, RCX, RDX, R8, R9, R10, R11 are considered volatile and must be considered destroyed on function calls.
The registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15 are considered nonvolatile and must be saved and restored by a function that uses them.
Underlying hardware architecture specifies certain level of calling standards; however the operating system can deviate from the architecturally defined calling standards. Windows defines several calling conventions. The most common calling conventions are
C call
Std call
This call
Fast call
CLR call
In this post, we’ll discuss C call and STD call. For now we are dealing with a x86 bit machine.
C call (or __cdecl according to MSDN)
Default calling convention for C and C++ applications. Caller pushes arguments, executes call instruction, once the function has returned - caller cleans the stack.
Argument passing from right to left, arguments are pushed on the stack. Registers are not used.
Caller is responsible for cleaning up the stack for the parameters passed to the called function. Due to this images are comparatively larger.
Functions symbolized with “_” prefix when you look at them symbol table.
STD call
This is the convention used by all win32 API. Caller pushes arguments into the stack, executes call instruction, the callee cleans up the stack by executing RET N - where n is the number of bytes allocated by caller.
Argument passing from right to left, arguemnts are pushed on the stack. Registers are not used.
Called routine responsible for cleaning up the stack even for the parameters. Caller continues without any further actions.
Functions symbolized with “_” prefix and @ after the function name.
Thats it for now, I’ll cover Fast call in the next post.