Stack balance of __cdecl and _stdcall

Source: Internet
Author: User

All kinds of books about VC are written in how many:

1. _stdcall calling convention: The function's parameters are passed from right to left through the stack, and the called function cleans the memory stack of the transfer parameters before returning.
2. __cdecl is the default calling method for C and C + + programs. each function that calls it contains the code that empties the stack , so the resulting executable file size is larger than the call to the _stdcall function. The function uses a right-to-left compression stack. Note: For variable parameter member functions, always use the __cdecl conversion method.


__cdecl

To be honest, a lot of beginners are still very puzzled about this description, what is the difference between the two methods of invocation?

Let's start by looking at the following code:

void Fun1 (char *a, int n) {for (int i = 0; i < n; i++) {std::cout << A;}} int _tmain (int argc, _tchar* argv[]) {char *t = "abcdefg\n"; int n = 3;__asm{push npush tcall fun1}system ("pause"); return 0; }
Of course, FUN1 is called by default __cdecl, and running the code we found an error message when calling Main to return:


That is, the ESP is not equal to ESI before the RET and does not successfully return to the stack state before the function call. "The main module saves the return address on the stack when calling the exported function of the DLL (ESP-XXX). When a function call returns, the stack gets the return address (ESP + XXX), which returns to the main module. "

Now understand, we call the function in the __cdecl way, the caller is responsible for the function of the stack, to ensure the stack balance, so we need to clear the stack after the call fun1, here according to the 2 parameters of the loading stack, we only need to add the add esp,8 after calling Fun1 to achieve the stack balance.

That is, the code changes to:

__asm{push npush tcall Fun1add esp,8}

_stdcall

void _stdcall fun2 (char *a, int n) {for (int i = 0; i < n; i++) {std::cout << A;}} int _tmain (int argc, _tchar* argv[]) {char *t = "abcdefg\n"; int n = 3;__asm{push npush tcall fun2}system ("pause"); return 0; }
that is: here fun2 call mode is _stdcall, from the above code, the calling function does not do any clear stack fun2 processing, fun2 function inside the stack processing.


So here's the problem.

We don't know how to call a function. Very simply, we save the ESP before calling the function, and then recover the ESP after the call is complete:

void __cdecl fun1 (char *a, int n) {for (int i = 0; i < n; i++) {std::cout << A;}} void __stdcall fun2 (char *a, int n) {for (int i = 0; i < n; i++) {std::cout << A;}} int _tmain (int argc, _tchar* argv[]) {char *t = "abcdefg\n"; int n = 3;unsigned long Dwesp;__asm{mov dwesp, Esppush npush TC All Fun1call Fun2mov ESP, dwesp}system ("pause"); return 0;}
Success!


Stack balance of __cdecl and _stdcall

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.