_ Stdcall & _ cdecl call Convention

Source: Internet
Author: User
Tags microsoft c

 

_ Stdcall: The parameter pressure stack is in the C language Order (from right to left), but unlike the C language, it is cleared by the caller from the stack, therefore, its compilation file is smaller than _ cdecl. _ Stdcall is the default call convention in Windows API functions. VB and VFP also use this convention.
_ Cdecl is the default calling method used by C language. It supports variable parameter calls such as printf.
In addition, VC ++ has different name conversion methods for the two call methods.

In C, suppose we have a function like this:
  
Int function (int A, int B)
  
You can use this function by using result = function. However, when a high-level language is compiled into a machine code that can be recognized by a computer, a problem arises: In the CPU, the computer cannot know how many or what parameters are required for a function call, and there is no hardware to save these parameters. That is to say, the computer does not know how to pass parameters to this function. The operation of passing parameters must be coordinated by the function caller and the function itself. Therefore, the computer provides a data structure called Stack to support parameter transmission.

Stack is an advanced post-release data structure with a storage zone and a stack top pointer. The stack top Pointer Points to the first available data item (called the stack top) in the stack ). You can add data to the stack at the top of the stack. This operation is called the push operation. After the stack is pressed, the top of the stack automatically becomes the position of the newly added data item, the stack top pointer is also modified. You can also remove the top stack from the stack, which is called pop. After the stack pops up, an element at the top of the stack changes to the top of the stack, and the top pointer of the stack changes accordingly.

When a function is called, the caller pushes the parameter to the stack in sequence and then calls the function. After the function is called, the caller obtains data in the stack for calculation. After function compute is completed, the caller or the function modifies the stack to restore the original stack.

Two important issues in parameter passing must be clarified:
  
When there are more than one parameter, in what order will the parameter be pushed into the stack?
Who will restore the original stack after the function is called?
In advanced languages, the two problems are described through the function call convention. Common call conventions include:

Stdcall
Cdecl
Fastcall
Thiscall
Naked call

 

Stdcall call conventions
Stdcall is often referred to as Pascal's call convention, because Pascal is a very common programming language for teaching in the early days, and its syntax is rigorous. The function call Convention used is stdcall. In Microsoft C ++ C/C ++ compilers, Pascal macro is often used to declare this call Convention. Similar macros include winapi and callback.

The syntax of the stdcall call Convention Declaration is (the previous function is used as an example ):
  
Int _ stdcall function (int A, int B)
  
The call Convention of stdcall means: 1) the parameter is pushed from right to left into the stack, 2) the function modifies the stack itself. 3) the function name is automatically followed by a leading underline followed by a @ symbol, followed by the parameter size

The preceding function is used as an example. parameter B is first pushed to the stack, and parameter A is followed. The function call function (1, 2) is translated into an assembly language:

Push 2 second parameter into Stack
Push 1 first parameter into Stack
Call function call parameters. Note that CS: EIP is automatically added to the stack.

For the function itself, you can translate it:
Push EBP to save the EBP register, which will be used to save the stack top pointer of the stack and can be restored when the function exits.
MoV EBP, esp save Stack pointer
MoV eax, [EBP + 8 h] EBP in the stack is stored in order with EBP, CS: EIP, A, B, EBP + 8 pointing to
Add eax, [EBP + 0ch] B is saved at EBP + 12 in the stack
MoV ESP and EBP resume ESP
Pop EBP
RET 8

During compilation, the function name is translated into _ FUNCTION @ 8.

Note that different compilers insert their own compilation code to provide compilation versatility, but the general code is as follows. The ESP is reserved to EBP at the beginning of the function, and the restoration at the end of the function is a common method used by the compiler.

From the perspective of function calls, 2 and 1 are pushed into the stack sequentially, and in the function, they access parameters through the offset relative to EBP (that is, the stack pointer when the function is just introduced. After the function is completed, RET 8 indicates that the 8-byte stack is cleared and the function restores the stack.

  
Cdecl call conventions
The cdecl call Convention, also known as the C call Convention, is the default call Convention of C language. Its definition syntax is:

Int function (int A, int B) // The C call convention is not modified.
Int _ cdecl function (int A, int B) // specify C call conventions

When I wrote this article, I was surprised to find that the parameter pressure stack sequence in cdecl call conventions is the same as that in stdcall. The parameter is first pushed to the stack from right to left. The difference is that the function itself does not clean up the stack, and the caller is responsible for clearing the stack. Due to this change, the number of parameters allowed by the C call convention is not fixed, which is also a major feature of C language. For the previous function, the assembly code after cdecl is changed:

Call Process
Push 1
Push 2
Call Function
Add ESP, 8 Note: here the caller is restoring the stack

Called function _ Function
Push EBP to save the EBP register, which will be used to save the stack top pointer of the stack and can be restored when the function exits.
MoV EBP, esp save Stack pointer
MoV eax, [EBP + 8 h] EBP in the stack is stored in order with EBP, CS: EIP, A, B, EBP + 8 pointing to
Add eax, [EBP + 0ch] B is saved at EBP + 12 in the stack
MoV ESP and EBP resume ESP
Pop EBP
RET note: the stack is not modified here

According to msdn, this modifier is automatically prefixed with a leading underline before the function name. Therefore, the function name is recorded as _ function in the symbol table, but this change does not appear to me during compilation.

Because the parameters are pressed from the right to the left, the initial parameter is at the position closest to the top of the stack. Therefore, when an indefinite number of parameters are used, the position of the first parameter in the stack must be known. As long as the number of parameters is determined based on the explicit parameters of the first and later, the parameter can be used, for example, the sprintf function in CRT is defined:
Int sprintf (char * buffer, const char * format ,...)
Since all the indefinite parameters can be determined through format, it is no problem to use the indefinite number of parameters.

Fastcall
The fastcall call Convention is similar to stdcall, which means:
  
The first and second DWORD parameters (or smaller ones) of the function are passed through ECx and EDX, and other parameters are pushed from right to left
Call function to clear the stack
Function Name modification rules are the same as stdcall
Statement Syntax: int fastcall function (int A, int B)

Thiscall
Thiscall is the only function modifier that cannot be explicitly specified, because thiscall is not a keyword. It is the default call Convention for C ++ class member functions. Because the member function call has a this pointer, special processing is required. thiscall means:

Parameter from right to left into Stack
If the number of parameters is determined, this pointer is passed to the caller through ECx; if the number of parameters is not determined, this pointer is pushed to the stack after all parameter pressure stacks. If the number of parameters is not fixed, the caller clears the stack. Otherwise, the function cleans the stack by itself. To illustrate this call Convention, the following classes and codes are defined:

Class
{
Public:
Int function1 (int A, int B );
Int function2 (int ,...);
};

Int A: function1 (int A, int B)
{
Return A + B;
}

# Include <stdarg. h>
Int A: function2 (int ,...)
{
Va_list AP;
Va_start (AP, );
Int I;
Int result = 0;
For (I = 0; I <A; I ++)
{
Result + = va_arg (AP, INT );
}
Return result;
}

Void callee ()
{
A;
A. function1 (1, 2 );
A. function2 (3, 1, 2, 3 );
}

After the callee function is translated into an assembly, it becomes:
// Function function1 call
00401c1d push 2
00401c1f Push 1
00401c21 Lea ECx, [ebp-8]
00401c24 call function1 note that this is not included in the stack

// Function function2 call
00401c29 Push 3
00401c2b push 2
00401c2d Push 1
00401c2f Push 3
00401c31 Lea eax, [ebp-8] Here introducing this pointer
00401c34 push eax
00401c35 call function2
00401c3a add ESP, 14 h
  
It can be seen that, when the number of parameters is fixed, it is similar to stdcall. If it is not scheduled, it is similar to cdecl.

Naked call
This is a rare call Convention. Generally, it is recommended that you do not use it. The compiler does not add initialization and cleanup code for such functions. More specifically, you cannot use return to return values. You can only use insert assembly to return results. This is generally used for real-Mode Driver Design. Suppose we define a sum addition program, which can be defined:

_ Declspec (naked) int add (int A, int B)
{
_ ASM mov eax,
_ ASM add eax, B
_ ASM RET
}

Note: This function does not return an explicit return value. The returned result is implemented by modifying the eax register, and the RET commands that exit the function must be explicitly inserted. The code above is translated into an assembly and then changed:

MoV eax, [EBP + 8]
Add eax, [EBP + 12]
RET 8

Note that this modifier is used in combination with _ stdcall and cdecl. The code used in combination with cdecl is mentioned earlier. For the code combined with stdcall, it becomes:

_ Declspec (naked) int _ stdcall function (int A, int B)
{
_ ASM mov eax,
_ ASM add eax, B
_ Asm ret 8 // pay attention to the following 8
}

This function is called in the same way as the common cdecl and stdcall call functions.

Common problems caused by function call conventions
If the defined and used conventions are inconsistent, the stack will be damaged, leading to serious problems. The following are two common problems:

The function prototype declaration and function body definition are inconsistent.
Different function conventions are defined during DLL Function Import.
For example, if we declare a function in dll:

_ Declspec (dllexport) int func (int A, int B); // note that stdcall is not found here and cdecl is used.
The time code used is:

Typedef int (* winapi dllfunc) func (int A, int B );
Hlib = loadlibrary (...);

Dllfunc func = (dllfunc) getprocaddress (...) // The call conventions are modified here
Result = func (); // cause Error

This modifier is added because the caller does not understand the meaning of winapi. The code above will inevitably cause the stack to be destroyed. The checkesp function inserted during MFC compilation will tell you that the stack is damaged.

 

1) calling convention)

Determines the order in which function parameters are transferred to and from the stack. The caller or the caller pushes the parameter to the stack and the modifier used by the compiler to identify the function name. Function call conventions include:

1. _ stdcall call conventions

It is equivalent to the Pascal call Convention frequently used in 16-bit dynamic libraries. In 32-bit VC ++ 5.0, Pascal's call Convention is no longer supported (in fact, it has been defined as _ stdcall. Function parameters are passed from right to left through the stack. The called function clears the memory stack of the transfer parameter before returning.

_ 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 (use _ cdecl)

The parameter is pushed from right to left to the stack. The caller pushes the parameter 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 ).

_ 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. It is the default MFC call convention.

3. _ fastcall call conventions

"Man" is 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 Dwords) for smaller parameters, the remaining parameters are still transmitted from the right to the left pressure stack, and the called function clears the memory stack of the transfer parameter before returning ).

_ 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 call conventions

Applies only 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 conventions

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 ++/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.

 

2) Name modification conventions

1. decoration name)

"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 function name modification conventions vary with the compilation types (C or C ++) and call conventions.

Rules for modifying function names during a and c Compilation:

_ Stdcall call conventions:

Add an underline prefix before the output function name, followed by a "@" symbol and the number of bytes of the parameter, in the format of _ functionname @ number.

_ Cdecl:

Add an underline prefix to the name of the output function in the format of _ functionname.

_ Fastcall:

Add a "@" symbol before the output function name, followed by a "@" symbol and the number of bytes of its parameter, in the format of @ 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:

Take "? "Mark the start of the function name, followed by the function name;
The function name starts with "@ YG" to identify the parameter table, followed by the parameter table;
The parameter table is represented in 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. The code behind the pointer indicates the pointer type. If a pointer of the same type persists, it is replaced by "0". A "0" indicates a repetition;

The first item of the parameter table is the type of the return value of the function, followed by the Data Type of the parameter, and the pointer mark is before the data type referred to by the parameter table;
The end of the name is marked with "@ Z" after the parameter table. If this function has no parameters, it ends with "Z. 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 ". The "_ cedcl" Declaration for the function can only be called by C/C ++.

_ Fastcall:

The rules are the same as the _ stdcall call Convention above, except that the start identifier of the parameter table changes from "@ YG" to "@ Yi ".

Article Source: http://www.diybl.com/course/3_program/c++/cppjs/2008617/126024.html

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.