1. Save the Register
First, the C false Stator Program The values of the following registers are saved: EBX, ESI, EDI, EBP, Cs, DS, SS, and es. This does not mean that they cannot be modified within the subroutine. Instead, it indicates that if the subroutine changes their values, the original values must be restored before the subroutine returns. Values of EBX, ESI, and EDI cannot be changed because C uses these registers for register variables. Generally, the stack is used to save the original values of these registers.
2. Function Name
Most C compilers add an underscore before the function name and global or static variable. For example, the function name F will be specified as _ F rather than F. The Linux GCC compiler does not include any characters. In the executable Linux elf, for C function f, you only need to simply use the function name f. However, the GCC of djgpp adds an underline.
3. PASS Parameters
According to the C call convention, the parameters of a function are pushed into the stack in a certain order, which is in the opposite order as they appear in the function.
Consider this c statement: printf ("x = % d \ n", x); shows how to compile this statement (in the equivalent NASM format ). The status of the stack after the start part of the printf function is executed. The printf function is a C language library function that can carry any parameter. The rules stipulated in the C call Convention are specifically stipulated to allow these types of functions. Because the format string is finally pushed into the stack, no matter how many parameters are passed to the function, its position in the stack will always be EBP + 8. Then printf Code You can view the location of the format string to determine how many parameters need to be passed and how to find them on the stack.
Of course, if an error occurs in printf ("x = % d \ n"), the printf code will still output Dual Characters in [EBP + 12, this is not the value of X. Segment. Data
X dd 0
Format DB " X = % d \ n " , 0
Segment. Text
Push DWORD [x] ; Push the value of X into the stack.
Push DWORD format ; Push the address of the format string into the stack.
Call _ Printf ; Underline!
Add ESP, 8 ; Remove parameters from Stack
4. Calculate the address of the local variable
It is very easy to find the variable address defined in the data or BSS segment. Basically, the connection program does this. However, it is not easy to calculate the address of a local variable (or parameter) on the stack. However, this requirement is very common when a subroutine is called. Consider passing the address of a variable (let's call it X) to a function (let's call it foo. If X is in the EBP-8 position of the stack, you cannot use it like this:
MoV eax, ebp-8
Why? Because the value stored in eax by the instruction mov must be calculated by the assembler (that is, it must be a constant at last ). However, there is a command to do this. It is the load balancing tive address ). The following code calculates the address of x and stores it in eax:
Lead eax, [ebp-8]
Now eax has the address of X, and when calling the function Foo, it can be pushed to the stack.
5. return value
A value is returned after the C function is executed. The C call Convention specifies how to do this. The returned values must be transmitted through registers. All Integer types (char, Int, Enum, etc.) are returned through the eax register. If they are smaller than 32 bits, they will be extended to 32 bits when stored in eax. The 64-bit value is returned through the edX: eax register. Floating Point Number patrol is in the st0 register of the mathematical coprocessor.
6. Other Call conventions
All 80x86 C compilers support the rules described above in the Standard C call conventions. Generally, the compiler supports other call conventions. It is very important to know the call conventions used by the compiler to call your functions when the rain-proof assembly language interfaces are used. Generally, there is a lack of time and the standard call conventions are used. However, this is not always the case. Compilers that use multiple conventions have command line switches that can be used to change the default conventions. They also provide extended C syntax to specify a call Convention for a single function. However, the extension standards of each compiler can be different.
The GCC compiler allows different call conventions. The extension syntax _ attribute _ can be used to specify a function call convention. For example, to declare a function F with a NULL return value with an int parameter, use the following syntax to declare its circle using the standard call Convention:
Void F (INT) _ attribute _ (cdecl ));
GCC also supports standard call conventions. By replacing cdecl with stdcall, the above function can be specified to use this convention. The difference between stdcall and cdecl is that stdcall requires the subroutine to remove the parameter from the stack (the same as Pascal's call Convention ). Therefore, the stdcall call Convention can only be used for functions with fixed parameters.
Borland and Microsoft use the same syntax to declare the call conventions. They add the keywords _ cdecl and _ stdcall in the C code. These keywords are used to modify the function. In the prototype Declaration, they appear before the function name:
Void _ cdecl F (INT );
Each call Convention has its own advantages and disadvantages. Cdecl is simple and flexible. It can be used for any type of C functions and C compilers. Using other conventions limits the portability of subprograms. Its main disadvantage is that it runs slowly and uses more memory than other conventions.
The main advantage of the stdcall call convention is that it uses less memory than cdecl. You do not need to clear the stack after the call command. Its main drawback is that it cannot be used for Variable Parameter functions.