Function call conventions and stacks

Source: Internet
Author: User
Document directory
  • 1. What is a stack?
  • 2. function call conventions
  • Example 3: __cdecl and _ stdcall
Posting time: 11:41:00
Function call conventions and stack 1 What is a stack?

The compiler generally uses stacks for function calls. A stack is a region of storage. In an embedded environment, a programmer sometimes needs to define an array as a stack. Windows automatically maintains a stack for each thread, and the stack size can be set. The compiler uses a stack to stack the parameters and local variables of each function.

Function calls are often nested. At the same time, the stack contains information about multiple functions, and each function occupies a continuous zone. The area occupied by a function is called frame ).

The compiler uses the stack from the high address. Suppose we define an array a [1024] As the stack space. At first, the top pointer of the stack points to a [1023]. If there are two functions A and B in the stack, and a calls B, the top pointer of the stack points to the frame of function B. If function B returns. The top pointer of the stack points to the frame of function. If there are too many things in the stack that cause overflow, the damage is the things above a [0.

In a multi-threaded (task) environment, the CPU Stack pointer points to the memory area that is currently used. An important task of switching threads is to set the stack pointer to the top address of the stack of the current thread.

Different CPUs may have different stack la S and function call methods for different compilers, but the basic concepts of stacks are the same.

2. function call conventions

The function call conventions include the order in which parameters are passed and who is responsible for clearing the stacks occupied by parameters, for example:

  Parameter transfer order Who is responsible for clearing the stack occupied by parameters?
_ Pascal Left to right Caller
_ Stdcall From right to left Called function
_ Cdecl From right to left Caller

The code for calling a function and the called function must use the same function call convention to run the program normally. In Windows, __cdecl is the default function call Convention for C/C ++ programs.

On Some CPUs, the compiler transmits parameters using registers. The stacks used by functions are allocated and released by the called functions. This call Convention has one thing in common with _ cdecl: The inconsistent number of real parameters and form parameters will not cause a stack error.

However, when using registers to pass parameters, the compiler will save the parameters in the registers to the specified position in the stack when entering the function. Parameters should have a place in the stack like local variables. The parameter can be understood as a local variable that calls a function to specify the initial value.

Example 3: __cdecl and _ stdcall

The STACK layout may be different for different CPUs and compilers. This article takes the x86, VC ++ compiler as an example.

The VC ++ compiler no longer supports function call conventions such as _ Pascal, _ Fortran, and _ syscall. Currently, only _ cdecl and _ stdcall are supported.

The stack content of a program that uses the call method of _ cdecl or _ stdcall is the same when it first enters the subfunction. The top of the stack pointed to by ESP is the return address. This is pushed into the stack by the call command. The following are the parameters, the left parameter is on the top, and the right parameter is on the bottom (first on the stack ).

As shown in the previous table, the difference between __cdecl and _ stdcall is: __cdecl is the stack occupied by the caller to clean up the parameter, and __stdcall is the stack occupied by the parameter of the called function to clean up the parameter.

Since the called function of _ stdcall must know the exact number of input parameters during compilation (the called function must clear the stack), variable parameter functions, such as printf, cannot be supported. In addition, if the caller uses an incorrect number of parameters, a stack error occurs.

By viewing the assembly code, the __cdecl function call will have a stack adjustment statement after the call statement, for example:

    A = 0x1234;
    B = 0x5678;
    C = add (A, B );

Corresponding x86 assembly:

    MoV dword ptr [ebp-4], 1234 H
    MoV dword ptr [ebp-8], 5678 H
    MoV eax, dword ptr [ebp-8]
    Push eax
    MoV ECx, dword ptr [ebp-4]
    Push ECx
    Call 0040100a
    Add ESP, 8
    MoV dword ptr [ebp-0Ch], eax

_ Stdcall function calls do not need to adjust the stack:

    Call 00401005
    MoV dword ptr [ebp-0Ch], eax

Function

    Int _ cdecl add (int A, int B)
    {
    Return A + B;
    }

Generate the following Assembly Code (debug version ):

    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]
    MoV eax, dword ptr [EBP + 8]
    Add eax, dword ptr [EBP + 0ch]
    Pop EDI
    Pop ESI
    Pop EBX
    MoV ESP, EBP
    Pop EBP
    RET // jump to the address specified by ESP and ESP + 4 to point ESP to the first parameter when it enters the Function

Check the implementation of the _ stdcall function, and you will find that the function is different from the last line of the _ cdecl function:

    RET 8 // execute RET and clear the stack occupied by Parameters

For the debug version, the VC ++ compiler adds the code for checking esp when "directly calling the address", for example:

    Ta = (Tadd) Add; // Tadd definition: typedef int (_ cdecl * Tadd) (int A, int B );
    C = TA (A, B );

Generate the following assembly code:

    MoV [ebp-10h], 0040100a
    MoV ESI, ESP
    MoV ECx, dword ptr [ebp-8]
    Push ECx
    MoV edX, dword ptr [ebp-4]
    Push edX
    Call dword ptr [ebp-10h]
    Add ESP, 8
    Cmp esi, ESP
    Call _ chkesp (004011e0)
    MoV dword ptr [ebp-0Ch], eax

The _ chkesp code is as follows. If ESP is not equal to the value saved before the function call, the error code is returned.

    004011e0 JNE _ chkesp + 3 (004011e3)
    004011e2 RET
    004011e3; error handling code

The _ chkesp error handling dialog box is displayed. The ESP value is incorrect when a function call is reported. The release version of assembly code is much simpler. Also, _ chkesp is not added. In the event of an ESP error, the program continues to run until "you need to close the problem ".

4. Additional instructions

The function call Convention only describes the relationship between the "Code for calling a function" and the called function.

Assume that function a is _ stdcall, and function B calls function. You must use the function declaration to tell the compiler that function a is _ stdcall. The compiler will naturally generate the correct call code.

If function a is _ stdcall. However, when referencing function A, you tell the compiler that function a is in the _ cdecl mode and the compiler generates code in the _ cdecl mode, which is inconsistent with the call Convention of function, an error occurs.

Using Delphi to call VC functions as an example, Delphi uses the _ Pascal Convention by default, and VC uses the _ cdecl Convention by default. We generally set the VC function to _ stdcall, for example:

    Int _ stdcall add (int A, int B );

In Delphi, declare this function as _ stdcall, and you can call it:

    Function add (A: integer; B: integer): integer;
    Stdcall; External 'a. dll ';

Because it may be called by programs in other languages, many APIs use the _ stdcall call convention.

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.