• 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.

  • 相关阅读:
    ie浏览器下,get请求缓存问题
    grunt 单独压缩多个js和css文件【转】
    初次接触nodejs,请多指教。
    浮躁是一种流行病【转】
    php安装配置那些事(本文纯属个人记事与技术无关)
    读取年份数组中的所有周六周天
    C#窗体中读取修改xml文件
    Power BI brief introduction
    D365 CRM online trial application
    TalkingData Cocos2dx集成指南【最新】
  • 原文地址:https://www.cnblogs.com/quark/p/2658545.html
Copyright © 2020-2023  润新知