Measure the test taker's understanding about the call methods of _ stdcall and _ cdecl.

Source: Internet
Author: User

Both _ stdcall and _ cdecl are agreed Keywords of function call. The difference between the two is given first, and then the example is analyzed:

_ Stdcall: the parameter is pushed from right to left into the stack, and the stack is cleared by the function itself.


_ Cdecl: the parameter is also pushed from right to left into the stack, but the stack is cleared by the caller.


In addition, these two variables and functions have different names under the same name Modification Convention. For details, see another blog: analysis on naming conventions extern "C" and extern "C ++"

 

 

The following is an example:

 

[Cpp]
# Include "stdio. h"
# Include <iostream>
# Include <Windows. h>
# Include <conio. h>
 
Using namespace std;
 
Int _ stdcall Func_stdcall (int nParam1, int nParam2)
{
Return 1;
}
 
Int _ cdecl Func_cdecl (int nParam1, int nParam2)
{
Return 1;
}
 
Int main ()
{
Int a = Func_stdcall (1, 2 );
 
A = Func_cdecl (1, 2 );
 
Return 0;
}

# Include "stdio. h"
# Include <iostream>
# Include <Windows. h>
# Include <conio. h>

Using namespace std;

Int _ stdcall Func_stdcall (int nParam1, int nParam2)
{
Return 1;
}

Int _ cdecl Func_cdecl (int nParam1, int nParam2)
{
Return 1;
}

Int main ()
{
Int a = Func_stdcall (1, 2 );

A = Func_cdecl (1, 2 );

Return 0;
}
The above code is compiled in the XP + VC ++ 6.0 SP6 environment. The compiled assembly code is as follows:

 

 
 

First, we need to clarify the functions of several commands in the assembly code:


1. call: press the EIP of the next call command into the stack, and then jump to the @ address and run the command;


2. ret: pop up the current data of the stack to the EIP and continue to execute;


3. ret n: n indicates an integer. The current data in the stack is popped up to the EIP. Then, the ESP value is added with n, and the execution continues.


Let's look at the assembly code again. When calling Func_stdcall and Func_cdecl, the caller (main function) pushes the parameter to the stack, note that values 0x00401127, 0x00401129, 0x00401133, and 0x00401135 are first pushed to 2 and then to 1. This order is the order in which function parameters are pushed from right to left.


Pay attention to the address 0x0040110F, which is the exit command for calling Func_stdcall. "ret 8" first pops up the EIP value, and then adds the ESP value to 8, it is equivalent to performing two operations on the stack. Because the compiling environment is 32-bit, calling Func_stdcall is actually two 32-bit integer values, which are exactly 8 bytes. Then run the command at the EIP address. The EIP value should be 0x00401130, which is the next command of the call command. This command assigns the returned value to variable. It can be seen that the stack is cleaned internally by Func_stdcall, but not by external callers.


Then let's take a look at the Func_cdecl modified by _ cdecl. Note that the address 0x0040111B has only one command "ret". Only the current value of the stack is popped up to the EIP and the operation continues. However, two 32-bit integer values have been pushed before the call, and the stack has not been cleared. Let's take a look at the commands that continue to be executed. The commands at address 0x0040113C are the commands that continue to be executed, and the commands are "add esp, 8". This is easy to understand, adding 8 to the esp value is equivalent to performing two out-of-stack operations. But this is done by the caller (main parameter), so the stack is cleaned by the caller.

 

 

_ Stdcall is usually used in Windows APIs. You can see the following code:


[Cpp]
# Define CALLBACK _ stdcall
# Define WINAPI _ stdcall
# Define WINAPIV _ cdecl
# Define APIENTRY WINAPI
# Define APIPRIVATE _ stdcall
# Define PASCAL _ stdcall
# Define cdecl _ cdecl
 
# Ifndef CDECL
# Define CDECL _ cdecl
# Endif

# Define CALLBACK _ stdcall
# Define WINAPI _ stdcall
# Define WINAPIV _ cdecl
# Define APIENTRY WINAPI
# Define APIPRIVATE _ stdcall
# Define PASCAL _ stdcall
# Define cdecl _ cdecl

# Ifndef CDECL
# Define CDECL _ cdecl
# Endif
The default call method of C and C ++ programs is _ cdecl, which is the default setting of VC ++ 6.0. Therefore, without explicitly specifying the call conventions, generally, the _ cdecl method is used. When dealing with Windows APIs, _ stdcall is explicitly used to ensure consistency with Windows APIs.

 

 

 



In addition, it should be noted that functions such as printf that support variable parameters do not know how many parameters the caller will pass or how many parameters will be pressed into the stack, therefore, the function itself cannot clean up the stack, and the caller can only clean up the stack.


 

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.