Call the function to call calling conventions demystified

Source: Internet
Author: User

Http://www.codeproject.com/cpp/calling_conventions_demystified.asp

The original post is very good. I am too lazy to translate it... Ga.

  • __cdeclIs the default calling convention for C and C ++ programs. the advantage of this calling convetion is that it allows functions with a variable number of arguments to be used. the disadvantage is that it creates larger executables.
  • __stdcallIs used to call Win32 API functions. It does not allow functions to have a variable number of arguments.
  • __fastcallAttempts to put arguments in registers, rather than on the stack, thus making function callfaster.
  • ThiscallCalling convention is the default calling convention used by C ++ member functions that do not use variable arguments.
  • Introduction

    During the long, hard, but yet beautiful process of learning C ++ programming for Windows, you have probably been curious about the strange specifiers that sometime appear in front of function declarations, like__cdecl,__stdcall,__fastcall,WINAPI, Etc. After looking through msdn, or some other reference, you probably found out that these specifiers specifyCalling conventionsFor functions. in this article, I will try to explain different calling conventions used by Visual C ++ (and probably other Windows C/C ++ compilers ). I emphasize that above mentioned specifiers are Microsoft-specific, and that you shoshould not use them if you want to write portable code.

    So, what are the calling conventions? When a function is called, the arguments are typically passed to it, and the return value is retrieved. A calling Convention describesHowThe arguments are passed and values returned by functions. It also specifies how the function names are decorated. Is it really necessary to understand the calling conventions to write good C/C ++ programs? Not at all. However, it may be helpful with debugging. Also, it is necessary for linking C/C ++ with assembly code.

    To understand this article, you will need to have some very basic knowledge of assembly programming.

    No matter which calling convention is used, the following things will happen:

    1. All arguments are widened to 4 bytes (on Win32, of course), and put into appropriate memory locations. these locations are typically on the stack, but may also be in registers; this is specified by calling conventions.
    2. Program Execution jumps to the address of the called function.
    3. Inside the function, registers ESI, EDI, EBX, and EBP are saved on the stack. The part of code that performs these operations is calledFunction PROLOGAnd usually is generated by the compiler.
    4. The function-specific code is executed, and the return value is placed into the eax register.
    5. Registers ESI, EDI, EBX, and EBP are restored from the stack. The piece of code that does this is calledFunction epilog, And as with the function Prolog, in most cases the compiler generates it.
    6. Arguments are removed from the stack. This operation is calledStack cleanupAnd may be passed med either inside the called function or by the caller, depending on the calling convention used.

    As an example for the calling conventions (wait tThis), We are going to use a simple function:

    int sumExample (int a, int b){return a + b;}

    The call to this function will look like this:

    int c = sum (2, 3);

    For _ cdecl, _ stdcall, and _ fastcall calling conventions, I compiled the example code as C (not c ++ ). the function name decorations, mentioned later in the article, apply to the C decoration schema. c ++ name decorations are beyond the scope of this article.

    C calling convention (_ cdecl)

    This Convention is the default for C/C ++ programs (compiler option/Gd ). if a project is set to use some other calling convention, we can still declare a function to use _ cdecl:

    int __cdecl sumExample (int a, int b);

    The main characteristics of _ cdecl calling convention are:

    1. Arguments are passed from right to left, and placed on the stack.
    2. Stack cleanup is saved med by the caller.
    3. Function name is decorated by prefixing it with an underscore character '_'.

    Now, take a look at an example of A _ cdecl call:

    ; // push arguments to the stack, from right to leftpush        3    push        2    ; // call the functioncall        _sumExample ; // cleanup the stack by adding the size of the arguments to ESP registeradd         esp,8 ; // copy the return value from EAX to a local variable (int c)mov         dword ptr [c],eax 

    The called function is shown below:

    ; // function prolog  push        ebp    mov         ebp,esp   sub         esp,0C0h   push        ebx    push        esi    push        edi    lea         edi,[ebp-0C0h]   mov         ecx,30h   mov         eax,0CCCCCCCCh   rep stos    dword ptr [edi]   ; //return a + b;  mov         eax,dword ptr [a]   add         eax,dword ptr [b] ; // function epilog  pop         edi    pop         esi    pop         ebx    mov         esp,ebp   pop         ebp    ret              
    Standard calling convention (_ stdcall)

    This Convention is usually used to call Win32 API functions. In fact,WINAPIIs nothing but another name__stdcall:

    #define WINAPI __stdcall

    We can explicitly declare a function to use__stdcallConvention:

    int __stdcall sumExample (int a, int b);

    Also, we can use the compiler option/GZTo specify__stdcallFor all functions not explicitly declared with some other calling convention.

    The main characteristics__stdcallCalling Convention are:

    1. Arguments are passed from right to left, and placed on the stack.
    2. Stack cleanup is saved med by the called function.
    3. Function name is decorated by prepending an underscore character and appending a' @ 'character and the number of bytes of stack space required.

    The example follows:

    ; // push arguments to the stack, from right to left  push        3      push        2      ; // call the function  call        _sumExample@8; // copy the return value from EAX to a local variable (int c)    mov         dword ptr [c],eax 

    The function code is shown below:

    ; // function prolog goes here (the same code as in the __cdecl example); //return a + b;  mov         eax,dword ptr [a]   add         eax,dword ptr [b] ; // function epilog goes here (the same code as in the __cdecl example); // cleanup the stack and return  ret         8 

    Because the stack is cleaned by the called function,__stdcallCalling Convention creates smaller executables__cdecl, In which the code for Stack cleanup must be generated for each function call. On the other hand, functions with the variable number of arguments (likeprintf()) Must use__cdecl, Because only the caller knows the number of arguments in each function call; therefore only the caller can perform the stack cleanup.

    Fast calling convention (_ fastcall)

    Fast calling Convention indicates that the arguments shoshould be placed in registers, rather than on the stack, whenever possible. this operation CES the cost of a function call, because operations with registers are faster than with the stack.

    We can explicitly declare a function to use__fastcallConvention as shown:

    int __fastcall sumExample (int a, int b);

    We can also use the compiler option/GRTo specify__fastcallFor all functions not explicitly declared with some other calling convention.

    The main characteristics__fastcallCalling Convention are:

    1. The first two function arguments that require 32 bits or less are placed into registers ECx and EDX. The rest of them are pushed on the stack from right to left.
    2. Arguments are popped from the stack by the called function.
    3. Function name is decorated by prepending a' @ 'character and appending a' @ 'and the number of bytes (decimal) of space required by the arguments.

    Note: Microsoft have reserved the right to change the registers for passing the arguments in future compiler versions.

    Here goes an example:

    ; // put the arguments in the registers EDX and ECX  mov         edx,3   mov         ecx,2   ; // call the function  call        @fastcallSum@8  ; // copy the return value from EAX to a local variable (int c)    mov         dword ptr [c],eax 

    Function Code:

    ; // function prolog  push        ebp    mov         ebp,esp   sub         esp,0D8h   push        ebx    push        esi    push        edi    push        ecx    lea         edi,[ebp-0D8h]   mov         ecx,36h   mov         eax,0CCCCCCCCh   rep stos    dword ptr [edi]   pop         ecx    mov         dword ptr [ebp-14h],edx   mov         dword ptr [ebp-8],ecx ; // return a + b;  mov         eax,dword ptr [a]   add         eax,dword ptr [b] ;// function epilog    pop         edi    pop         esi    pop         ebx    mov         esp,ebp   pop         ebp    ret              

    How fast is this calling convention, comparing__cdeclAnd__stdcall? Find out for yourselves. Set the compiler option/GR, And compare the execution time. I didn't find__fastcallTo be any faster than other calling conventons, but you may come to different conclusions.

    Thiscall

    ThiscallIs the default calling convention for calling member functions of C ++ classes (using t for those with a variable number of arguments ).

    The main characteristicsthiscallCalling Convention are:

    1. Arguments are passed from right to left, and placed on the stack.thisIs placed in ECx.
    2. Stack cleanup is saved med by the called function.

    The example for this calling convention had to be a little different. first, the code is compiled as C ++, and not C. second, we have a struct with a member function, instead of a global function.

    struct CSum{int sum ( int a, int b) {return a+b;}};

    The assembly code for the function call looks like this:

      push        3      push        2      lea         ecx,[sumObj]   call        ?sum@CSum@@QAEHHH@Z; CSum::sum   mov         dword ptr [s4],eax

    The function itself is given below:

      push        ebp    mov         ebp,esp   sub         esp,0CCh   push        ebx    push        esi    push        edi    push        ecx    lea         edi,[ebp-0CCh]   mov         ecx,33h   mov         eax,0CCCCCCCCh   rep stos    dword ptr [edi]   pop         ecx    mov         dword ptr [ebp-8],ecx   mov         eax,dword ptr [a]   add         eax,dword ptr [b]   pop         edi    pop         esi    pop         ebx    mov         esp,ebp   pop         ebp    ret         8    

    Now, what happens if we have a member function with a variable number of arguments? In that case,__cdeclIs used, andthisIs pushed onto the stack last.

    Conclusion

    To cut a long story short, we'll outline the main differences between the calling conventions:

    • __cdeclIs the default calling convention for C and C ++ programs. the advantage of this calling convetion is that it allows functions with a variable number of arguments to be used. the disadvantage is that it creates larger executables.
    • __stdcallIs used to call Win32 API functions. It does not allow functions to have a variable number of arguments.
    • __fastcallAttempts to put arguments in registers, rather than on the stack, thus making function callfaster.
    • ThiscallCalling convention is the default calling convention used by C ++ member functions that do not use variable arguments.

    In most cases, this is all you'll ever need to know about the calling conventions

    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.