quark

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

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.

posted on 2012-08-27 14:38  QuarkZ  阅读(295)  评论(0编辑  收藏  举报