On function call agreement
Source: unknown Author: unknown
In the C language, suppose we have such a function:
Int Function (Int A, INT B)
This function can be used as long as you use the result = function (1, 2) in such a way. However, when the senior language is compiled into a computer code that the computer can be identified, there is a problem to conveze: in the CPU, the computer has no way to know how many, what kind of parameters are required, no hardware can save these parameters . That is, the computer does not know how to deliver parameters to this function, and the work of passing the parameters must be coordinated by the function caller and function itself. To this end, the computer provides a data structure called a stack to support parameter transmission.
The stack is an advanced data structure, and the stack has a storage area, a stack top pointer. The stack top pointer points to the first available data item in the stack (called a stack top). The user can add data in the top of the stack top, and this operation is called a press. After the stack, the stack is automatically turned into the location of the newly added data item, and the top pointer is also modified. The user can also take the top of the stack from the stack, called the pop-up (POP), after the pop-up stack, one element under the top of the stack becomes the top of the stack, and the top pointer needs to be modified.
When the function is called, the caller sequentially stacks the parameters, then calls the function, after the function is called, and the data is obtained in the stack and calculates. After the function calculation ends, or the caller, or the function itself modifies the stack to restore the stack to the original.
In parameter delivery, there are two important issues to be clearly stated:
When the number of parameters is more than one, the parameters are pressed into the stack function, and who will restore the stack to the original
In advanced languages, these two issues will be described through function call conventions. Common calls agree:
Stdcall CDECL FastCall thiscall Naked Call
STDCALL call convention
STDCALL is often called the Pascal call agreement, because Pascal is a very common teaching computer programming language, its grammar is rigorous, and the function call convention used is stdcall. In the C / C compiler of the Microsoft C series, this call is often used in Pascal macro, and similar macros has WinAPI and Callback.
The syntax for stdcall call the agreed statement (for the function of the previous article as an example):
INT __STDCALL FUNCTION (Int A, INT B)
Stdcall's call agreement means: 1) Parameter from the right direction left press stack, 2) Function itself Modify the stack 3) Function name Automatically add the debord, followed by a @ symbol, followed by the size of the parameters
Take the above function as an example, the parameter b first is punched, then the parameter A, the function calls Function (1, 2) call to the assembly language will become:
Push 2 second parameter into the stack
Push 1 first parameter
Call function calls the parameters, pay attention to this time automatically put the CS: EIP
For the function itself, you can translate:
PUSH EBP Saves the EBP register that will be used to save the stack top pointer, you can recover when the function exits
MOV EBP, ESP Save Stack Pointer
MOV EAX, [EBP 8H] stacking EBP points before the location of the EBP, CS: EIP, A, B, EBP 8 point to A
Add EAX, [EBP 0CH] Stack EBP 12 is saved in BMOV ESP, EBP Restore ESP
POP EBP
Ret 8
When compiling, the name of this function is translated into _function @ 8
Note that different compilers will insert their assembly code to provide the versatility of compilation, but the general code is. Where the ESP to EBP is retained at the beginning of the function, the end recovery is a common method of compiler.
From the function call, 2 and 1 are sequentially inserted by the PUSH, and in the function, in the function, the offset access parameters are passed through the offset relative to the EBP (i.e., the stack pointer when the function is justified). After the function is over, RET 8 indicates the stack of 8 bytes, and the function restores the stack.
CDECL call convention
CDECL call agreed is also known as C call convention, is a C language default call agreement, and its definition syntax is:
INT Function (int A, int b) // does not add modification is C call convention
INT __CDECL FUNCTION (INT A, INT B) / / Clearly indicates C call conventions
When writing this article, I am unexpected, I found that the parameter stack order of the CDECL call agreed is that the parameter is the same, the parameter first is pressed into the stack to the left. The difference is that the function itself does not clean up the stack, and the caller is responsible for cleaning the stack. Due to this change, the number of C-call conventions allow the number of parameters of the function is not fixed, which is also a major feature of the C language. For the previous FUNCTION function, the assembly code after using CDECL becomes:
Call
Push 1
Push 2
Call function
Add ESP, 8
Note: Here the caller in the restore stack
Called function _function
PUSH EBP Saves the EBP register that will be used to save the stack top pointer, you can recover when the function exits
MOV EBP, ESP Save Stack Pointer
MOV EAX, [EBP 8H] stacking EBP points before the location of the EBP, CS: EIP, A, B, EBP 8 point to A
Add EAX, [EBP 0CH] Stacking in EBP 12 Save B
MOV ESP, EBP Recovery ESP
POP EBP
RET
Note that there is no modification of the stack here.
In MSDN, the modification automatically adds a predecessor before the function name, so the function name is recorded in _function in the symbol table, but I don't see this change when compiling.
Since the parameters are sequenced from the right to left, the first parameter is closest to the top of the stack, so when the number of parameters are used, the position of the first parameter in the stack can certainly know, as long as the parameters are not The number can be determined according to the first latter subsequent parameters, you can use an unproducible parameter, such as the Sprintf function in the CRT, is defined as:
INT Sprintf (Char * Buffer, Const Char * Format, ...)
Since all uncertain parameters can be determined via Format, there is no problem with the parameters of the number of applications.
FastCall
FastCall call agreement and stdcall are similar, which means:
The first and second DWORD parameters of the function (or smaller size) passed through ECX and EDX, other parameters pass the modified function cleaning stack function name modification rules with stdcall by stacking the stack function name
Its declaration syntax is: int FastCall Function (Int A, INT B)
Thiscall
ThisCall is the only function modification that cannot be explicitly indicated because thisCall is not a keyword. It is a C class member function default call agreement. Since the member function call has a THIS pointer, this must be handled, thiscall means: Parameters are passed from right to left into the argument, the THIS pointer passes the caller by ECX; if the number of parameters is uncertain, this The pointer is pressed into the stack after all parameter stacks. Number of parameters, the caller cleaning the stack, otherwise the function clensizes the stack
To illustrate this calling convention, define as follows and using code:
Class A
{
PUBLIC:
Int Function1 (Int A, INT B);
INT Function2 (Int A, ...);
}
Int a :: function1 (int A, int b)
{
RETURN A B;
}
#include
Int A :: function2 (int A, ...)
{
VA_LIST AP;
VA_START (AP, A);
INT I;
Int results = 0;