_cdecl和_stdcall的最大区别就是__cdecl是由调用者释放堆栈,而__stdcall由被调用者释放堆栈。
默认情况下,c/c++编译器都是_cdecl,除非显示指名为_stdcall。当然,一般在C/C++层次下,我们是不用关心具体这是怎么实现的,因为编译器已经帮助我们处理了,但是看看汇编代码有助于我们理解这两种函数调用方式是怎么回事。
_cdecl由主调函数清栈
//实例代码 _cdecl#include<iostream>
using namespace std;
void add(int &a,int &b)
{
a += b;
}
int main()
{
int a = 3, b = 4;
add(a , b);
return 0;
}
add函数汇编代码如下:
00401390 push %ebp00401391 mov %esp,%ebp
00401393 mov 0x8(%ebp),%ecx
00401396 mov 0x8(%ebp),%edx
00401399 mov 0xc(%ebp),%eax
0040139C mov (%eax),%eax
0040139E add (%edx),%eax
004013A0 mov %eax,(%ecx)
004013A2 pop %ebp
004013A3 ret //木有自己清栈
//实例代码 _stdcall
#include<iostream>
using namespace std;
void _stdcall add(int &a,int &b)
{
a += b;
}
int main()
{
int a = 3, b = 4;
add(a , b);
return 0;
}
add汇编代码
00401390 push %ebp00401391 mov %esp,%ebp
00401393 mov 0x8(%ebp),%ecx
00401396 mov 0x8(%ebp),%edx
00401399 mov 0xc(%ebp),%eax
0040139C mov (%eax),%eax
0040139E add (%edx),%eax
004013A0 mov %eax,(%ecx)
004013A2 pop %ebp
004013A3 ret $0x8 //清除8个字节,add自己清栈