In these conventions the caller cleans the arguments from the stack, which allows for variable argument lists, eg. printf().
cdecl
The cdecl calling convention is used by many C systems for the x86 architecture. In cdecl, function parameters are pushed on the stack in a right-to-left order. Function return values are returned in the EAX register (except for floating point values, which are returned in the x87 register ST0). Registers EAX, ECX, and EDX are available for use in the function.
For instance, the following C code function prototype and function call:
int function_name(int, int, int); int a, b, c, x; ... x = function_name(a, b, c);
will produce the following x86 Assembly code (written in MASM syntax, with destination first):
push c push b push a call function_name add esp, 12 ;Stack clearing mov x, eax
The calling function cleans the stack after the function call returns.
There are some variations in the interpretation of cdecl, particularly in how to return values. As a result, x86 programs compiled for different operating system platforms and/or by different compilers can be incompatible, even if they both use the “cdecl” convention and do not call out to the underlying environment. Some compilers return simple data structures with the length of 2 registers or less in EAX:EDX, and larger structures and class objects requiring special treatment by the exception handler (e.g., a defined constructor, destructor, or assignment) are returned in memory. To pass “in memory”, the caller allocates memory and passes a pointer to it as a hidden first parameter; the callee populates the memory and returns the pointer, popping the hidden pointer when returning.
In Linux/gcc double/floating point values should be pushed on the stack via the x87 pseudo-stack. Like so:
sub esp,8; make room for the double fld [ebp+x]; load our double onto the floating point stack fstp [esp]; push our double onto the stack call func; add esp,8;
Using this method ensures it is pushed on the stack in the correct format.
The cdecl calling convention is usually the default calling convention for x86 C compilers, although many compilers provide options to automatically change the calling conventions used. To manually define a function to be cdecl, some support the following syntax:
void _cdecl function_name(params);
The _cdecl modifier must be included in the function prototype, and in the function declaration to override any other settings that might be in place.
syscall
This is similar to cdecl in that arguments are pushed right to left. EAX, ECX, and EDX are not preserved. The size of the parameter list in doublewords is passed in AL.
Syscall is the standard calling convention for 32 bit OS/2 API.
optlink
Arguments are pushed right to left. The three lexically first (leftmost) arguments are passed in EAX, EDX, and ECX and up to four floating-point arguments are passed in ST(0) through ST(3), although space for them is reserved in the argument list on the stack. Results are returned in EAX or ST(0). Registers EBP, EBX, ESI, and EDI are preserved.
Optlink is used by the IBM VisualAge compilers.