Function call method-_ thiscall and _ cdecl ,__ stdcall

Source: Internet
Author: User

Function call Method -- _ thiscall and _ cdecl ,__ stdcall

First, __thiscall is a class call method. The biggest difference between it and other call methods is:
_ Thiscall adds a class pointer parameter to each function.
Class AA
{
Void BB (int cc );
};
In fact, the original form of the BB function is void BB (AA & this, int CC );
This is the call method of _ thiscall.

Secondly, we know that there are several Calling methods for function calling, mainly divided into C and Pascal. in C and C ++, C-type calls are default, and the default call of class member functions is _ stdcall. There is a difference between the two. Here we use an example to describe:

1. _ cdecl: Default call methods for C and C ++
Example:
Void input (Int & M, Int & N);/* equivalent to void _ cdecl input (Int & M, Int & N );*/
The following is the compilation code:
00401068 Lea eax, [ebp-8]; get [ebp-8] address (ebp-8), save to eax
0040106b push eax; then press the stack
00401_c Lea ECx, [ebp-4]; take [ebp-4] address (ebp-4), save to ECx
0040366f push ECx; then press the stack
00401070 call @ ILT + 5 (input) (0040100a); then call the Input Function
00401075 add ESP, 8; restore Stack

From the process of calling the input function can be seen: Before calling this function, first press the stack ebp-8, and then press the stack ebp-4, then call the function input, finally input function call after the end, use ESP + 8 to restore the stack. It can be seen that in C language calls, the default function modifier _ cdecl is used for parameter pressure stack and stack restoration by the main function call.

What is the address ebp-8 and ebp-4? Select debug windows under VC view, and then select registers to display the register variable value. Then, select memory under debug windows, enter the value of the ebp-8 and the value of the ebp-4 (or directly enter the ebp-8 and-4) to see what the two addresses actually store, which is actually the address of the Variable N (ebp-8 ), M address (ebp-4), it can be seen that in the main call function for real parameters of the Pressure stack and the order is from right to left. In addition, because the real parameter is a reference to the corresponding variable, it also proves that the reference actually passes the address of the variable (similar to a pointer ). Conclusion: In C or C ++ language calls, the default function modifier _ cdecl is used. The primary function calls the function to perform parameter pressure stack and resume stack, the pressure stack sequence of real parameters is from right to left, and the stack is restored by the main function. Because the main call function manages the stack, variable parameters can be implemented. In addition, the naming method is to add a line (_) before the function (_).

2. winapi (actually Pascal, callback, _ stdcall)
Example:
Void winapi input (Int & M, Int & N );
Let's take a look at the calling assembly code:
00401068 Lea eax, [ebp-8]
0040106b push eax
00401_c Lea ECx, [ebp-4]
0040366f push ECx
00401070 call @ ILT + 5 (input) (0040100a)

From the process of calling the input function can be seen: Before calling this function, first press the stack ebp-8, then press the stack ebp-4, then call the function input, after calling the function input, there is no corresponding stack recovery (for other function calls, so I did not list it). Next I will list the assembly code of the input function itself: (this function is not actually big, however, the compilation example is a little larger. You can check the intermediate code before and after it is irrelevant to this example)

39: void winapi input (Int & M, Int & N)
40 :{
00401110 push EBP
00401111 mov EBP, ESP
00401113 sub ESP, 48 h
00401116 push EBX
00401117 push ESI
00401118 push EDI
00401119 Lea EDI, [ebp-48h]
0040111c mov ECx, 12 h
00401121 mov eax, 0 cccccccch
00401126 rep STOs dword ptr [EDI]
41: int S, I;
42:
43: While (1)
00401128 mov eax, 1
0040112d test eax, eax
0040112f je input + 0c1h (004011d1)
44 :{
45: printf ("/nplease input the first number M :");
00401135 push offset string "/nplease input the first number M"... (0020.b8)
0040113a call printf (00401530)
0040113f add ESP, 4
46: scanf ("% d", & M );
00401142 mov ECx, dword ptr [EBP + 8]
00401145 push ECx
00401146 push offset string "% d" (000000b4)
0040114b call scanf (004015f0)
00401150 add ESP, 8
47:
48: If (M = s)
004011b3 mov eax, dword ptr [EBP + 8]
004011b6 mov ECx, dword ptr [eax]
004011b8 CMP ECx, dword ptr [ebp-4]
004011bb JL input + 0afh (004011bf)
57: break;
004011bd JMP input + 0c1h (004011d1)
58: else
59: printf ("m <n * (n + 1)/2, please input again! /N ");
004011bf push offset string "m <n * (n + 1)/2, please input agai"... (00426060)
004011c4 call printf (00401530)
004011c9 add ESP, 4
60 :}
004011cc JMP input + 18 h (00401128)
61:
62 :}
004011d1 pop EDI
004011d2 pop ESI
004011d3 pop EBX
004011d4 add ESP, 48 h
004011d7 cmp ebp, ESP
004011d9 call _ chkesp (004015b0)
004011de mov ESP, EBP
004011e0 pop EBP
004011e1 RET 8

Later, we can see that at the end of the function, there is RET 8, which is obviously the restoration stack, because in 32-bit C ++, the variable address is 4 bytes (Int Is also 4 bytes), so the two addresses on the stack are 8 bytes. From this we can see that the main call function is responsible for the stack pressure, and the called function is responsible for restoring the stack. Therefore, variable parameter functions cannot be implemented, because the called function cannot know the number of bullet stacks in advance, but this can be done in the main function, because the number of parameters is determined by the main function.

Next let's take a look at what the ebp-8 and ebp-4 addresses actually store, the ebp-8 address stores the N value, and EBP-4 stores the m value. It also applies parameter transfer from right to left.

Conclusion: _ stdcall is responsible for Stack pressure in the main call function, parameters in the stack Are popped up in the called function, and stack recovery. Therefore, the variable parameter function cannot be implemented. The parameter is passed from right to left. In addition, the naming modification method is to add an underscore (_) to the front of the function, and there is a symbol (@) after the function name (@), after @, the number of bytes occupied by the parameter in the parameter list (10 hexadecimal), for example, void input (Int & M, Int & N), is modified: _ INPUT @ 8 callback is used for most API functions and window message processing functions. Therefore, before calling the function, the main function will first press the stack, and then the API function restores the stack.

For example:
Push edX
Push EDI
Push eax
Push EBX
Call getdlgitemtexta

Finally, when outputting an API function in the SDK, winapi is often used to agree on the function. In Win32, winapi is defined as _ stdcall function calling conventions, here is a brief introduction:


1. The _ stdcall call convention is equivalent to the Pascal call convention that is frequently used in 16-bit dynamic libraries. In 32-bit VC ++ 5.0, Pascal's call Convention is no longer supported (in fact, it has been defined as _ stdcall. In addition to _ Pascal, __fortran and _ syscall are not supported). Instead, they are replaced by the _ stdcall call convention. The two are essentially the same, that is, the function parameter is passed from right to left through the stack. The called function clears the memory stack of the transfer parameter before returning, but the difference is the function name modifier section (the modification section of the function name will be described in detail later ).

_ Stdcall is the default calling method of the PASCAL program. It is usually used in Win32 API. The function uses the stack pressure method from right to left and clears the stack when it exits. After compiling a function, VC adds an underline prefix to the function name, and adds "@" and the number of bytes of the parameter to the function name.

2. c call conventions (which are described by the _ cdecl keyword) are pushed to the stack in sequence from right to left. The caller pushes the parameters to the stack. The memory stack of the transfer parameter is maintained by the caller (because of this, the function that implements the variable parameter can only use this call Convention ). In addition, the function name modification conventions are also different.

_ Cdecl is the default call Method for C and C ++ programs. Every function that calls it contains the code to clear the stack. Therefore, the size of the executable file generated is larger than that of the call to the _ stdcall function. The function uses the stack pressure mode from right to left. After compiling a function, VC adds an underline prefix to the function name. Is the default MFC call convention.


3. The _ fastcall call convention is "person" as its name. Its main feature is fast because it transmits parameters through registers (in fact, it uses ECx and EDX to transmit the first two DWORD or smaller parameters, and the remaining parameters are still transmitted from the right to the left pressure stack, the called function clears the memory stack of the transfer parameter before returning). In terms of the function name modification conventions, it is different from the previous two.

_ Fastcall functions use registers to pass parameters. After compiling a function, VC adds the "@" prefix to the function name, and adds "@" and the number of parameters after the function name.

4. thiscall is only applied to "C ++" member functions. This pointer is stored in the Cx register and the parameter is pressed from right to left. Thiscall is not a keyword and cannot be specified by programmers.

5. Naked call uses 1-4 call timing. If necessary, the compiler will generate code to save the ESI, EDI, EBX, and EBP registers when entering the function, when you exit the function, the code is generated to restore the content of these registers. Naked call does not generate such code. The naked call is not a type modifier, so it must be used together with _ declspec.

The keywords _ stdcall, _ cdecl, and _ fastcall can be directly added before the function to be output, or in the setting environment... select/C ++/code generation. When the keywords added before the output function are different from those selected in the compiling environment, the keywords directly added before the output function are valid. Their corresponding command line parameters are/GZ,/GD, And/GR. The default status is/GD, Which is _ cdecl.

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.