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.