Calling Conventions
There are different calling conventions for different operating systems or different bits of system
or you compile with the vs (or others)
- Different conventions based on processor,OS,and Language Describe how are passed to functions
- Describe how are returned from functions
- Describe if the caller or callee
clean the stack
- Resonsible for function and
prologue
andepilogue
Windows x86 Calling Convention
Keyword | Stack cleanup | Parameter passing |
---|---|---|
__cdecl | Caller | Pushes parameters on the stack, in reverse order (right to left) |
__clrcall | n/a | Load parameters onto CLR expression stack in order (left to right). |
__stdcall | Callee | Pushes parameters on the stack, in reverse order (right to left) |
__fastcall | Callee | Stored in registers, then pushed on stack |
__thiscall | Callee | Pushed on stack; this pointer stored in ECX |
__vectorcall | Callee | Stored in registers, then pushed on stack in reverse order (right to left) |
- All arguments are widened to 32 bits(DWORD)
- Return value is widened to 32 bits(DWORD)
- Return values up to 32 bits are returned to
eax
register - Return values of 64 bit size(QWORD) are returned in EDX:EAX(The main value is in the EDX Register)
- Return Structures are returned by reference with a pointer in EAX
- Registers ESI,EDI,EBX,and EBP are restored(non-volatile)
- MSDN is your friend
__cdecl
Default calling convention for c and c++
Arguments are passed on the stack(pushed right-to-left)
Called is responsible for stack cleanup will (cdecl will clean the stack )
this is important when there are variadic functions,so function doesn’t
worry about stack cleaning.
Supports varag(variadic)functions
Example code below:
then we can get follow code with ida
- sub_401090 is the hello1 function
- sub_401000 is the addingNumberVariadic function which is variadic
- notice that caller clean the stack when the function return
__stdcall
The __stdcall
calling convention is used to call Win32 API functions. The callee cleans the stack
, so the compiler makes vararg
functions __cdecl
. Functions that use this calling convention require a function prototype. The __stdcall
modifier is Microsoft-specific.
Element | Implementation |
---|---|
Argument-passing order | Right to left. |
Argument-passing convention | By value, unless a pointer or reference type is passed. |
Stack-maintenance responsibility | Called function pops its own arguments from the stack. |
Name-decoration convention | An underscore (_ ) is prefixed to the name. The name is followed by the at sign (@ ) followed by the number of bytes (in decimal) in the argument list. Therefore, the function declared as int func( int a, double b ) is decorated as follows: _func@12 |
__fastcall
The __fastcall
calling convention specifies that arguments to functions are to be passed in registers, when possible. This calling convention only applies to the x86 architecture. The following list shows the implementation of this calling convention.
Element | Implementation |
---|---|
Argument-passing order | The first two DWORD or smaller arguments that are found in the argument list from left to right are passed in ECX and EDX registers; all other arguments are passed on the stack from right to left. |
Stack-maintenance responsibility | Called function pops the arguments from the stack. |
Name-decoration convention | At sign (@) is prefixed to names; an at sign followed by the number of bytes (in decimal) in the parameter list is suffixed to names. |
Case-translation convention | No case translation performed. |
__thiscall
The Microsoft-specific __thiscall
calling convention is used on C++ class member functions on the x86 architecture. It’s the default calling convention used by member functions that don’t use variable arguments (vararg
functions).
Under __thiscall, the callee cleans the stack
, which is impossible for vararg functions
. Arguments are pushed on the stack from right to left. The this
pointer is passed via register ECX, and not on the stack.
vararg
member functions use the__cdecl
calling convention. All function arguments are pushed on the stack, with thethis
pointer placed on the stack last.
Because this calling convention applies only to C++, it doesn’t have a C name decoration scheme.
When you define a non-static class member function out-of-line, specify the calling convention modifier only in the declaration. You don’t have to specify it again on the out-of-line definition. The compiler uses the calling convention specified during declaration at the point of definition.
__vectorcall
The __vectorcall
calling convention specifies that arguments to functions are to be passed in registers. __vectorcall
uses more registers for arguments than __fastcall
or the default x64 calling convention(rcx rdx r7 r8 [rsp+[size of arg]) use. The __vectorcall
calling convention is only supported in native code on x86 and x64 processors that include Streaming SIMD Extensions 2 (SSE2) and above. Use __vectorcall
to speed functions that pass several floating-point or SIMD vector arguments and perform operations that take advantage of the arguments loaded in registers. The following list shows the features that are common to the x86 and x64 implementations of __vectorcall
. The differences are explained later in this article.
to be continue one day
Reference:
https://docs.microsoft.com/en-us/cpp/cpp/argument-passing-and-naming-conventions?view=msvc-170