Call conventions (Calling convention) RefersProgramA protocol established to implement function calls in the design language. This Protocol specifies the parameter transfer mode in the function of the language, whether the parameter is variable, and who handles the stack. Different Languages define different call conventions.
In C ++, in order to allow Operator Overloading and function overloading, the C ++ compiler often rewrite the symbol names of each entry point according to certain rules, so that the same name (with different parameter types or different scopes) can have multiple usages without breaking the existing C-based linker. This technique is often called name mangling or name decoration ). Many C ++ compiler vendors have chosen their own name modification schemes.
Therefore, to enable modules written in other languages (such as Visual Basic applications, Pascal or Fortran applications) to call the DLL functions written in C/C ++, you must use the correct call conventions to export the function, and do not have the compiler modify the name of the function to be exported.
1 . Call conventions (Calling convention)
Call conventions are used to process the order of incoming and outgoing stacks when function parameters are transferred (by the caller or by the caller to bring the parameter to the stack ), the compiler is used to identify the name modification conventions of function names. Microsoft Vc ++ 6.0 defines the following call conventions. We will analyze them one by one based on the assembly language:
1, _ Cdecl
_ Cdecl is the call Convention used by C/C ++ and MFC programs by default. You can also add the _ cdecl keyword when declaring a function. When _ cdecl is used, function parameters are pushed to the stack in the order from right to left, and the caller pops up the parameter stack to clear the stack. Therefore, a function that implements variable parameters can only use this call convention. Every function using the _ cdecl Convention must containCodeTherefore, the size of the executable files generated is relatively large. _ Cdecl can be written as _ cdecl.
The following uses a specific example to analyze the _ cdecl Convention:
Create a Win32 console project in VC ++ and name it cdecl. The Code is as follows:
Int _ cdecl add (int A, int B); // function declaration
Void main ()
{
Add (1, 2); // function call
}
Int _ cdecl add (int A, int B) // function implementation
{
Return (A + B );
}
The disassembly code of the function call is as follows:
; Add (1, 2 );
Push 2; the parameter is pushed from right to left to 2 first
Push 1; press 1
Call @ ILT + 0 (ADD) (00401005); call function implementation
Add ESP, 8; clear stack by function call
2, _ Stdcall
_ Stdcall is used to call Win32 API functions. When _ stdcal is used, function parameters are written to the stack in the order from right to left. The called function clears the stack of the transfer parameter before returning, and the number of function parameters is fixed. Because the function body knows the number of passed parameters, the called function can directly clear the stack of the passed parameters with a RET n command before returning the result. _ Stdcall can be written as _ stdcall.
In this example, replace _ cdecl with _ stdcall:
Int _ stdcall add (int A, int B)
{
Return (A + B );
}
Disassembly code of function call:
; Add (1, 2 );
Push 2; the parameter is pushed from right to left to 2 first
Push 1; press 1
Call @ ILT + 10 (ADD) (0040100f); call function implementation
Disassembly code for function implementation:
; Int _ stdcall add (int A, int B)
Push EBP
MoV EBP, ESP
Sub ESP, 40 h
Push EBX
Push ESI
Push EDI
Lea EDI, [ebp-40h]
MoV ECx, 10 h
MoV eax, 0 cccccccch
Rep STOs dword ptr [EDI]
; Return (A + B );
MoV eax, dword ptr [EBP + 8]
Add eax, dword ptr [EBP + 0ch]
Pop EDI
Pop ESI
Pop EBX
MoV ESP, EBP
Pop EBP
RET 8; clear Stack
3, _ Fastcall
_ Fastcall conventions are used in scenarios with high performance requirements. _ Fastcall: The two DWORD parameters starting from the left of the function are placed in the ECX and EDX registers respectively, the other parameters are still transmitted from the right to the left pressure stack. The called function clears the stack of the transfer parameter before returning. _ Fastcall can be written as _ fastcall.
In this case, the function call convention is _ fastcall, and the number of function parameters is increased by two:
Int _ fastcall add (int A, double B, int C, int D)
{
Return (A + B + C + D );
}
Assembly Code of function call:
; Add (1, 2, 3, 4 );
Push 4; the last two parameters are pushed from right to left to 4
MoV edX, 3; put 3 of int type into edX
Push 40000000 h; press 2 of the Double Type
Push 0
MoV ECx, 1; Put 1 of int type into ECx
Call @ ILT + 0 (ADD) (00401005); call function implementation
Disassembly code for function implementation:
; Int _ fastcall add (int A, double B, int C, int D)
Push EBP
MoV EBP, ESP
Sub ESP, 48 h
Push EBX
Push ESI
Push EDI
Push ECx
Lea EDI, [ebp-48h]
MoV ECx, 12 h
MoV eax, 0 cccccccch
Rep STOs dword ptr [EDI]
Pop ECx
MoV dword ptr [ebp-8], EDX
MoV dword ptr [ebp-4], ECx
; Return (A + B + C + D );
Fild dword ptr [ebp-4]
FADD qword PTR [EBP + 8]
Fiadd dword ptr [ebp-8]
Fiadd dword ptr [EBP + 10 h]
Call _ ftol (004011b8)
Pop EDI
Pop ESI
Pop EBX
MoV ESP, EBP
Pop EBP
RET 0ch; clear Stack
The keywords _ cdecl, _ stdcall, and _ fastcall can be directly added before the function to be output, or in the setting environment... -> C/C ++-> code generation item selection. Their corresponding command line parameters are/GD,/GZ, And/GR. The default status is/GD, Which is _ cdecl. When the keywords added before the output function are different from those selected in the compiling environment, the keywords directly added before the output function are valid.
Explanation 1: Through stack transfer, the called function clears the memory stack of the transfer parameter before returning, but the difference is the function name modifier section (the modification section of the function name will be described in detail later ).
_ Stdcall is the default calling method of the PASCAL program. It is usually used in Win32 API. The function uses the stack pressure method from right to left and clears the stack when it exits. After compiling a function, VC adds an underline prefix to the function name, and adds "@" and the number of bytes of the parameter to the function name.
2. c call conventions (which are described by the _ cdecl keyword) are pushed to the stack in sequence from right to left. The caller pushes the parameters to the stack. The memory stack of the transfer parameter is maintained by the caller (because of this, the function that implements the variable parameter can only use this call Convention ). In addition, the function name modification conventions are also different.
_ Cdecl is the default call Method for C and C ++ programs. Every function that calls it contains the code to clear the stack. Therefore, the size of the executable file generated is larger than that of the call to the _ stdcall function. The function uses the stack pressure mode from right to left. After compiling a function, VC adds an underline prefix to the function name. Is the default MFC call convention.
3. The _ fastcall call convention is "person" as its name. Its main feature is fast because it transmits parameters through registers (in fact, it uses ECx and EDX to transmit the first two DWORD or smaller parameters, and the remaining parameters are still transmitted from the right to the left pressure stack, the called function clears the memory stack of the transfer parameter before returning). In terms of the function name modification conventions, it is different from the previous two.
_ Fastcall functions use registers to pass parameters. After compiling a function, VC adds the "@" prefix to the function name, and adds "@" and the number of parameters after the function name.
4. thiscall is only applied to "C ++" member functions. This pointer is stored in the Cx register and the parameter is pressed from right to left. Thiscall is not a keyword and cannot be specified by programmers.
5. Naked call uses 1-4 call timing. If necessary, the compiler will generate code to save the ESI, EDI, EBX, and EBP registers when entering the function, when you exit the function, the code is generated to restore the content of these registers. Naked call does not generate such code. The naked call is not a type modifier, so it must be used together with _ declspec.
The keywords _ stdcall, _ cdecl, and _ fastcall can be directly added before the function to be output, or in the setting environment... select \ C/C ++ \ code generation. When the keywords added before the output function are different from those selected in the compiling environment, the keywords directly added before the output function are valid. Their corresponding command line parameters are/GZ,/GD, And/GR. The default status is/GD, Which is _ cdecl.
To fully imitate Pascal's call convention, you must first use the _ stdcall call Convention. As for the function name Modification Convention, you can use other methods to imitate it. Another thing worth mentioning is winapi macro, windows. h supports this macro. It can translate the function into an appropriate call convention. In Win32, it is defined as _ stdcall. You can use the winapi macro to create your own APIs.
2) Name modification conventions
1. decoration name)
The "C" or "C ++" functions are identified by modifier internally (Compilation and link. Modifier is a string generated by the compiler when compiling a function definition or prototype. In some cases, modifying the name of a function is necessary, for example, specifying the output "C ++" overload function, constructor, and destructor in the module definition file, for example, call the "C" or "C ++" function in the assembly code.
Modifier names are jointly determined by function names, class names, call conventions, return types, parameters, and so on.
2. The name Modification Convention varies with the call convention and the compilation type (C or C ++. The function name modification conventions vary with the compilation type and call conventions.
Rules for modifying function names during a and c Compilation:
The _ stdcall call Convention adds an underline prefix before the output function name, followed by the "@" symbol and the number of bytes of the parameter. The format is _ functionname @ number.
The _ cdecl call Convention only adds an underline prefix before the output function name in the format of _ functionname.
_ Fastcall: add the "@" symbol before the output function name, followed by the "@" symbol and the number of bytes of the parameter. The format is @ functionname @ number.
They do not change the case sensitivity of the output function name. This is different from Pascal's call conventions. Pascal's output function names are not modified and all are capitalized.
B. Conventions for function name modification during C ++ Compilation:
__ stdcall call Conventions:
1. Start of the identification function name, followed by the function name;
2. After the function name, start with the parameter table marked by @ YG, followed by the parameter table;
3. The parameter table is represented by code:
X -- void,
d -- char,
E -- unsigned char,
f -- short,
H -- int,
I -- unsigned int,
j -- long,
K -- unsigned long,
m -- float,
n -- double,
_ n -- Bool,
....
pa -- indicates the pointer, and the code behind it indicates the pointer type. If the pointer of the same type appears consecutively, replace it with "0, A "0" indicates a repetition.
4. The first item in the parameter table is the return value type of the function, followed by the Data Type of the parameter, pointer identification before the data type it refers to;
5. mark the end of the entire name with "@ Z" after the parameter table. If the function has no parameters, end with the "Z" mark.
The format is "? Functionname @ YG ***** @ Z "or"? Functionname @ YG * xz ", for example
Int test1 (char * var1, unsigned long) ----- "? Test1 @ yghpadk @ Z"
Void Test2 () ----- "? Test2 @ ygxxz"
_ Cdecl:
The rules are the same as the _ stdcall call Convention above, except that the start mark of the parameter table is changed from "@ YG" to "@ ya ".
_ Fastcall:
The rules are the same as the _ stdcall call Convention above, but the start mark of the parameter table is changed from "@ YG" to "@ Yi ".
The "_ cedcl" Declaration for the function can only be called by C/C ++.
CB uses four modifiers for output function declaration.
// _ Cdecl
The default value of CB. It will add _ before the output function name and keep this function name unchanged. parameters are passed to the stack in sequence from right to left, it can also be written as _ cdecl and cdecl.
// _ Fastcall
The parameters of the function modified by her will be processed by registers with the intention of adding @ before the function name, and the parameters will be pushed to the stack in the order from left to right;
// _ Pascal
It indicates that the function name uses the naming convention in Pascal format. In this case, all function names are capitalized. The parameters are pressed from left to right;
// _ Stdcall
Use the standard function name. The function name will not change. When _ stdcall is used. The parameter can be set to _ stdcall in the order from right to left;
Explanation 2:
# Define callback _ stdcall
# Define winapi _ stdcall
Class = "apple-style-span" style = "font-family: ��; font-size: 12px;">
For example, for a function:
Void func (int A, int B, int C, int d ){}
Use the following functions:
Int main ()
{
Func (1, 2, 3, 4 );
}
1. If the function func is _ cdecl (the default call method), the call process is as follows:
Int main ()
{
// Stack pressure from right to left for parameters
Push 4
Push 3
Push 2
Push 1
Call func
Add ESP 0x10 // The caller restores the stack pointer esp. The size of the four parameters is 0x10 (4x4)
}
2. If the function func is _ stdcall, the calling process is as follows:
Int main ()
{
// Stack pressure from right to left for parameters
Push 4
Push 3
Push 2
Push 1
Call func
// The call func is responsible for recovering the stack pointer. The method is "RET 0x10"
}
3. If the function func is _ Pascal, the call is as follows:
Int main ()
{
// Press the stack from left to right for parameters
Push 1
Push 2
Push 3
Push 4
Call func
// The call func is responsible for recovering the stack pointer. The method is "RET 0x10"
}
4. if the function func is _ fastcall, the call is as follows
int main ()
{
// The parameters are first transmitted using ECx, EDX, and eax, then press the stack again
// do not go into the stack
// (for some reason, in the help, the information is transmitted from left to right.
// is the error message returned, or is the bcb6 and bcb5 different)
Push 4
mov ECx 3
mov edX 2
mov eax 1
call func
// restores the stack pointer from the caller func is responsible, the method is "RET 0x04",
// because only one parameter is included in the stack, the other parameters are passed in registers, therefore, use RET 0x04 to restore
}