zoukankan      html  css  js  c++  java
  • Stdcall and Cdecl

    This two call convention puzzels me since I knew them.

    MSDN explanations as below:

    _stdcall

    The __stdcall calling convention is used to call Win32 API functions. The callee cleans the stack.

    _cdecl

    This is the default calling convention for C and C++ programs. Because the stack is cleaned up by the caller.

    Let’s see my sample codes:

    MYDLL_API int _stdcall fnMyDll_Stdcall(int arg1)
    {
        return 42 + arg1;
    }
    
    MYDLL_API int _cdecl fnMyDll_Cdecl(int arg1)
    {
        return 42 + arg1;
    }

    We can find that the two methods above almost the same except the call convetion, one is _stdcall, the other is _cdecl.

    The calling codes:

    int _tmain(int argc, _TCHAR* argv[])
    {
        fnMyDll_Cdecl(1);
        fnMyDll_Stdcall(2);
        return 0;
    }

    well, all preparations are done. Let us focus on the details now!

    fnMyDll_Cdecl(1);
    0083151E  mov         esi,esp  
    00831520  push        1  
    00831522  call        dword ptr ds:[83935Ch]  
    00831528  add         esp,4      // this instruction clears the stack space~~
    0083152B  cmp         esi,esp  
    0083152D  call        __RTC_CheckEsp (083114Fh)  
    fnMyDll_Stdcall(2);
    00831532  mov         esi,esp  
    00831534  push        2  
    00831536  call        dword ptr ds:[839360h]  
    0083153C  cmp         esi,esp  
    0083153E  call        __RTC_CheckEsp (083114Fh)
    MYDLL_API int _cdecl fnMyDll_Cdecl(int arg1)
    {
    0FDA1420  push        ebp  
    0FDA1421  mov         ebp,esp  
    0FDA1423  sub         esp,0C0h  
    0FDA1429  push        ebx  
    0FDA142A  push        esi  
    0FDA142B  push        edi  
    0FDA142C  lea         edi,[ebp-0C0h]  
    0FDA1432  mov         ecx,30h  
    0FDA1437  mov         eax,0CCCCCCCCh  
    0FDA143C  rep stos    dword ptr es:[edi]  
        return 42 + arg1;
    0FDA143E  mov         eax,dword ptr [arg1]  
    0FDA1441  add         eax,2Ah  
    }
    0FDA1444  pop         edi  
    0FDA1445  pop         esi  
    0FDA1446  pop         ebx  
    0FDA1447  mov         esp,ebp  
    0FDA1449  pop         ebp  
    0FDA144A  ret
    MYDLL_API int _stdcall fnMyDll_Stdcall(int arg1)
    {
    0FDA1460  push        ebp  
    0FDA1461  mov         ebp,esp  
    0FDA1463  sub         esp,0C0h  
    0FDA1469  push        ebx  
    0FDA146A  push        esi  
    0FDA146B  push        edi  
    0FDA146C  lea         edi,[ebp-0C0h]  
    0FDA1472  mov         ecx,30h  
    0FDA1477  mov         eax,0CCCCCCCCh  
    0FDA147C  rep stos    dword ptr es:[edi]  
        return 42 + arg1;
    0FDA147E  mov         eax,dword ptr [arg1]  
    0FDA1481  add         eax,2Ah  
    }
    0FDA1484  pop         edi  
    0FDA1485  pop         esi  
    0FDA1486  pop         ebx  
    0FDA1487  mov         esp,ebp  
    0FDA1489  pop         ebp  
    0FDA148A  ret         4     // this instruction clear the parameter space in stack

    So It is clear what’s the difference between stdcall and cdecl. In programming, we should take care of the convention of methods. If the caller convention dismatches callee convention, things unexpected may happen.

  • 相关阅读:
    CentOS 6.3 下编译Nginx(笔记整理)
    XMPP协议相关基础概念(Strophe学习笔记)
    StackMapTable format error
    hibernate的子查询
    strophe与openfire模拟的XMPP简单hello程序
    Strophe.Status的所有值
    博客园添加SyntaxHighlighter
    P5395 【模板】第二类斯特林数·行
    test20191001
    test20190829
  • 原文地址:https://www.cnblogs.com/quark/p/2658545.html
Copyright © 2011-2022 走看看