In these conventions, the callee cleans up the arguments from the stack. Functions which use these conventions are easy to recognize in ASM code because they will
unwind the stack after returning. The x86 instruction allows an optional
16-bit parameter that specifies the number of stack bytes to release after returning to the caller. Such code looks like this: Conventions named or have not been standardized, and have been implemented differently, depending on the compiler vendor. 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. Return values are stored in the EAX register. stdcall is the standard calling convention for the Microsoft
Win32 API and for
Open Watcom C++.
Microsoft fastcall The Microsoft convention passes the first two arguments that fit (evaluated left to right) into ECX and EDX. Remaining arguments are pushed onto the stack from right to left. When the compiler compiles for
IA64 or
AMD64, it ignores the keyword (or any other calling convention keyword aside from #Microsoft vectorcall|) and uses
the Microsoft default 64-bit calling convention instead. Other compilers like
GCC and
Clang provide similar "fastcall" calling conventions, although they are not necessarily compatible with each other or with Microsoft fastcall. Consider the following C snippet: __attribute__((fastcall)) void printnums(int num1, int num2, int num3){ printf("The numbers you sent are: %d %d %d", num1, num2, num3); } int main(){ printnums(1, 2, 3); return 0; } x86 decompilation of the main function will look like (in Intel syntax): main: ; stack setup push ebp mov ebp, esp push 3 ; immediate 3 (third argument is pushed to the stack) mov edx, 0x2 ; immediate 2 (second argument) is copied to edx register. mov ecx, 0x1 ; immediate 1 (first argument) is copied to ecx register. call printnums mov eax, 0 ; return 0 leave retn The first two arguments are passed in the left to right order, and the third argument is pushed on the stack. There is no stack cleanup, as stack cleanup is performed by the callee. The disassembly of the callee function is: printnums: ; stack setup push ebp mov ebp, esp sub esp, 0x08 mov [ebp-0x04], ecx ; in x86, ecx = first argument. mov [ebp-0x08], edx ; arg2 push [ebp+0x08] ; arg3 is pushed to stack. push [ebp-0x08] ; arg2 is pushed push [ebp-0x04] ; arg1 is pushed push 0x8065d67 ; "The numbers you sent are %d %d %d" call printf ; stack cleanup add esp, 0x10 nop leave retn 0x04 As the two arguments were passed through the registers and only one parameter was pushed in the stack, the pushed value is being cleared by the retn instruction, as int is 4 bytes in size in x86 systems.
Microsoft vectorcall In
Visual Studio 2013, Microsoft introduced the calling convention in response to efficiency concerns from game, graphic, video/audio, and codec developers. The scheme allows for larger vector types (, , , ) to be passed in registers as opposed to on the stack. adds support for passing homogeneous vector aggregate (HVA) values, which are composite types (structs) consisting solely of up to four identical vector types, using the same six registers. Once the registers have been allocated for vector type arguments, the unused registers are allocated to HVA arguments from left to right. The positioning rules still apply. Resulting vector type and HVA values are returned using the first four XMM/YMM registers. For IA-32 and x64 code, is similar to and the
original x64 calling conventions respectively, but extends them to support passing vector arguments using
SIMD registers. In IA-32, the integer values are passed as usual, and the first six SIMD (
XMM/
YMM0-5) registers hold up to six floating-point, vector, or HVA values sequentially from left to right, regardless of actual positions caused by, e.g. an int argument appearing between them. In x64, however, the rule from the original x64 convention still apply, so that XMM/YMM0-5 only hold floating-point, vector, or HVA arguments when they happen to be the first through the sixth. vectorcall only handles the 256-bit (AVX, YMM) view of the vector registers. It does not cover the
AVX-512 (ZMM) view.
Intel register Before __vectorcall, ICC has a similar convention called , where as many parameters are stuffed into the registers as possible. It is also supported by clang. A variant of this ABI employing instead the x86_64 platform's usual System V calling convention with regard to register use is adopted by glibc's libmvec and supported by GCC, Clang, and ICC.
GNU and clang modifiers On 32-bit x86, GNU has a attribute that causes up to three non-variadic parameters to be passed in EAX, EDX, and ECX. It is less of its own calling convention and more of a modification that can be applied to existing calling conventions.
Borland register Evaluating arguments from left to right, it passes three arguments via EAX, EDX, ECX. Remaining arguments are pushed onto the stack, also left to right. It is the default calling convention of the 32-bit compiler of
Delphi, where it is known as
register. This calling convention is also used by Embarcadero's
C++Builder, where it is called
__fastcall. In this compiler,
Microsoft's fastcall can be used as
__msfastcall. GCC and Clang can be made to use a similar calling convention by using with the function attribute or the switch. (The stack order is inverted.) It is also possible to produce a caller clean-up variant using or extend this to also use SSE registers. A -based version is used by the Linux kernel on i386 since version 2.6.20 (released February 2007).
Watcom register Watcom does not support the
__fastcall keyword except to alias it to null. The register calling convention may be selected by command line switch. Up to 4 registers are assigned to arguments in the order EAX, EDX, EBX, ECX. Arguments are assigned to registers from left to right. If any argument cannot be assigned to a register (say it is too large) it, and all subsequent arguments, are assigned to the stack. Arguments assigned to the stack are pushed from right to left. Names are mangled by adding a suffixed underscore. Variadic functions fall back to the Watcom stack based calling convention. The Watcom C/C++ compiler also uses the directive that allows the user to specify their own calling convention. As its manual states, "Very few users are likely to need this method, but if it is needed, it can be a lifesaver".
TopSpeed, Clarion, JPI The first four integer parameters are passed in registers EAX, EBX, ECX and EDX. Floating point parameters are passed on the floating point stack – registers ST0, ST1, ST2, ST3, ST4, ST5 and ST6. Structure parameters are always passed on the stack. Added parameters are passed on the stack after registers are exhausted. Integer values are returned in EAX, pointers in EDX and floating point types in ST0.
safecall In
Delphi and
Free Pascal on
Microsoft Windows, the safecall calling convention encapsulates COM (
Component Object Model) error handling, thus exceptions aren't leaked out to the caller, but are reported in the
HRESULT return value, as required by COM/OLE. When calling a safecall function from Delphi code, Delphi also automatically checks the returned HRESULT and raises an exception if needed. The safecall calling convention is the same as the stdcall calling convention, except that exceptions are passed back to the caller in EAX as a HResult (instead of in FS:[0]), while the function result is passed by reference on the stack as though it were a final "out" parameter. When calling a Delphi function from Delphi this calling convention will appear just like any other calling convention, because although exceptions are passed back in EAX, they are automatically converted back to proper exceptions by the caller. When using COM objects created in other languages, the HResults will be automatically raised as exceptions, and the result for Get functions is in the result rather than a parameter. When creating COM objects in Delphi with safecall, there is no need to worry about HResults, as exceptions can be raised as normal but will be seen as HResults in other languages. Returns a result and raises exceptions like a normal Delphi function, but it passes values and exceptions as though it was: ==Either caller or callee clean-up==