__stdcall detailed understanding of the _stdcall (on)
In C, let's say we have one of these functions: int function (int a,int b)
This function can be used only in such a way that the result = function (1,2) is invoked. However, when a high-level language is compiled into machine code that can be identified by a computer, a problem emerges: in the CPU, the computer has no way of knowing how many, what parameters a function call requires, nor does it have the hardware to hold the parameters. In other words, the computer does not know how to pass arguments to this function, and the work of passing parameters must be coordinated by the function caller and the function itself. To do this, the computer provides a data structure called a stack to support parameter passing.
Stack is an advanced data structure, the stack has a storage area, a stack top pointer. The top of the stack pointer points to the first available data item (called the top of the stack) on the stack. Users can add data in the stack on the top of the stack, this operation is called the pressure stack (push), after the stack, the top of the stack automatically become the new data entry position, the top of the stack pointer also changes. Users can also take the stack from the top of the stack, known as pop-up stack (POP), pop-up stack, the top of the stack under the top of the stack, the top of the stack pointer changes. function calls, the caller sequentially presses the parameter stack, then calls the function, the function is called, obtains the data in the stack, and calculates. After the function is evaluated, either the caller, or the function itself, modifies the stack to restore the stack to its original.
There are two important issues that need to be clearly stated in parameter passing:
When the number of parameters is more than one, in what order the parameters are pressed into the stack function call, by WHO to restore the stack original. In a high-level language, these two issues are explained by a function call convention. The common calling conventions are:
Stdcall,cdecl,fastcall,thiscall,naked Call
StdCall calling convention:
StdCall is often called the Pascal calling convention, because Pascal is a very common teaching computer programming language, its syntax is rigorous, the use of the function of the call convention is stdcall. In the C + + compiler of the Microsoft C + + series, Pascal macros are often used to declare this calling convention, and similar macros include WINAPI and callback.
The syntax of the stdcall calling convention declaration is (for example, that function in the previous article):
int __stdcall function (int a,int b)
The calling convention of StdCall means: 1 The parameter is pressed from right to left to the stack, 2 the function itself modifies the stack 3 the functions are automatically underlined with a leading, followed by an @ symbol followed by the dimensions of the parameter.
Take the above function for example, the parameter B is first pressed stack, then the parameter a, function call functions (1,2) Call place
Translated into assembly language will become:
Push 2 second parameter into stack
Push 1 The first parameter into the stack
Call function calls arguments, note that the CS:EIP is automatically put into the stack at this time
And for the function itself, it can be translated as:
Push EBP Save the EBP register, which will be used to hold the stack top pointer, you can restore the Mov when the function exits Ebp,esp save stack pointer mov eax,[ebp + 8H] in the stack ebp point to position before saving EBP,CS:EIP,A,B,EBP + 8 Point A
Add EAX,[EBP + 0CH] EBP + 12 stored in stack b
MOV ESP,EBP restore ESP
Pop EBP
RET 8
And at compile time, the name of this function is translated into _function@8
Note that different compilers insert their own assembly code to provide the versatility of compilation, but the general code does so. where you keep esp in EBP at the beginning of the function, it is the compiler's common method to restore the function at the end.
From the function call, 2 and 1 are pushed into the stack in turn, while in the function the arguments are accessed by the offsets relative to the EBP (that is, the stack pointer when the new function is just entered). After the function ends, the RET 8 indicates that the 8-byte stack is cleaned up, and the function restores the stack itself.
CDECL calling convention:
The cdecl calling convention, also known as the C calling convention, is the default calling convention for the C language, and its definition syntax is:
int function (int a, int b)//No modification is the C calling convention
int __cdecl function (int a,int b)//explicitly indicates the C calling convention
In writing this article, to my surprise, I found that the parameters of the CDECL call agreement is the same as the stdcall, the parameters are first pushed to the left by the stack. The difference is that the function itself does not clean the stack, and the caller is responsible for scavenging the stack. Due to this change, the C calling convention allows the number of parameters of the function is not fixed, which is a major feature of C language. For the preceding function functions, the assembly code that uses the cdecl becomes:
Call Office
Push 1
Push 2
Call function
Add esp,8 Note: Here the caller is on the recovery stack
The called function _function the push EBP Save the EBP register, which is used to hold the stack's top pointer, which can be restored when the function exits
mov ebp,esp save stack pointer
mov eax,[ebp + 8H] Ebp in the stack before pointing to position save EBP,CS:EIP,A,B,EBP +8 Point A
Add EAX,[EBP + 0CH] EBP + 12 stored in stack b
MOV ESP,EBP restore ESP
Pop EBP
RET Note that there is no modified stack here
MSDN says that the modifier automatically preceded the function name with a leading underline, so the function name is recorded as _function in the symbol table, but I don't seem to see this change at compile time. Because the parameters are pressed from right to left in order to stack, so the first parameter is closest to the top of the stack, so when the indefinite number of parameters is used, the position in the stack is sure to know, as long as the indefinite number of parameters can be determined according to the first subsequent clear parameters, you can use indefinite parameters, For example, for the sprintf function in the CRT, it is defined as:
int sprintf (char* buffer,const char* format,...)
Since all indefinite parameters can be determined by format, it is no problem to use an indefinite number of parameters. Fastcall
The fastcall calling convention is similar to the stdcall, which means:
The first and second DWORD parameters (or smaller size) of the function are passed through ECX and edx, and the other parameters pass through the
From right to left in sequential press stack
called function cleanup stack
Function name modification rules with stdcall
Its declaration syntax is: int fastcall function (int a,int b)
ThisCall
ThisCall is the only function decoration that cannot be explicitly specified because thiscall is not a keyword. It is C + + class into
The default calling convention for the member function. Because the member function call also has a this pointer, it must be specially handled, th
The Iscall means:
Parameter from right to left into stack
If the number of arguments is determined, the this pointer is passed to the callee via ECX, and if the number of parameters is indeterminate, this pointer
After all parameters are pressed onto the stack.
The caller cleans up the stack on a variable number of arguments, otherwise the function cleans up the stack itself
To illustrate this calling convention, define the following class and use code: Class A
{
Public
int function1 (int a,int b);
int function2 (int a,...);
};
int a::function1 (int a,int b)
{
return a+b;
}
#i nclude
int a::function2 (int A,...)
{
Va_list ap;
Va_start (Ap,a);
int i;
int result = 0;
for (i = 0 I < a i + +)
{
result = Va_arg (ap,int);
}
return result;
}
void Callee ()
{
A A;
A.function1 (1,2);
A.function2 (3,1,2,3);
}
The callee function is translated into the Assembly and becomes:
function Function1 Call
0401C1D Push 2
00401C1F Push 1
00401c21 Lea Ecx,[ebp-8]
00401C24 Call Function1 Note that this is not being pushed into the stack
function Function2 Call
00401C29 Push 3
00401C2B Push 2
00401C2D Push 1
00401C2F Push 3
00401C31 Lea Eax,[ebp-8] Here introduce this pointer
00401C34 push EAX
00401C35 Call function2
00401C3A Add esp,14h
It can be seen that in the case of a fixed number of parameters, it is similar to stdcall, and is similar to cdecl
Naked Call
This is a very rare calling convention that the general programmer recommends not to use. The compiler does not add initialization and cleanup code to this function, and, more specifically, you cannot return the return value with the returns, only the results are returned using the Insert assembly. This is generally used for real-mode driver programming, assuming that the addition program that defines a sum can be defined as:
__declspec (naked) int add (int a,int b)
{
__ASM mov eax,a
__asm Add Eax,b
__ASM ret
}
Note that this function does not have an explicit return value returned by modifying the EAX register implementation, and the RET instruction for the Exit function must be explicitly inserted. The above code is translated into the assembly later into:
MOV Eax,[ebp+8]
Add eax,[ebp+12]
RET 8
Note that this modification is used in conjunction with __stdcall and Cdecl, which is preceded by the code used in conjunction with CDECL, and the code that binds to the stdcall, then becomes:
__declspec (naked) int __stdcall function (int a,int b)
{
__ASM mov eax,a
__asm Add Eax,b
__ASM RET 8//Note the following 8
}
As for this function being invoked, it is consistent with the normal cdecl and stdcall invocation functions. Common problems caused by function call conventions if the defined conventions and the conventions used are inconsistent, it will cause the stack to be corrupted, causing serious problems, and here are two common issues:
Inconsistent function prototype declaration and function Body definition
DLL Import function declares different function conventions
For example, suppose we declare a function in the DLL species:
__declspec (dllexport) int func (int a,int b);/Note that there is no stdcall here, using the
Cdecl
The code used is:
typedef int (*winapi DllFunc) func (int a,int b);
Hlib = LoadLibrary (...);
DllFunc func = (dllfunc) GetProcAddress (...) The calling convention is modified here
result = func (1,2);//Cause Error
Because the caller did not understand the meaning of WINAPI added to the modification, the code would inevitably cause the stack to be corrupted, MFC inserted at compile-time checkesp function will tell you that the stack is corrupted.
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