Friday, April 13, 2012

__stdcall、__cdecl、__thiscall、__fastcall的区别

=== cdecl ===
This calling convention is the default for C programs and also global functions in C++ programs. Generally the function arguments are passed on the stack in reverse order so that the callee can access them in the correct order. The caller is responsible for popping the arguments after the function returns, which makes it possible to use the ... to send runtime defined arguments. Return values are returned in the registers.
翻译:这种调用约定是C和C++程序默认的的。一般来说,函数参数反向压入栈中(即从右到左),那么被调用者就能按正确的顺序来访问它们。当函数返回时,由调用者负责清除栈中的参数。这样就使传递运行时参数成为可能(即传递可变参数)。函数返回值会存储在寄存器中。
=== stdcall ===
stdcall is the calling conventions used by the Win32 API. It is basically the same as the cdecl convention with the difference in that the callee is responsible for popping the arguments from the stack. This makes the call slightly faster, but also prevents the use of the ... operator.
翻译:stdcall是Win32 API函数的调用规范。它基本上和cdecl一样,只是它是由被调用函数负责栈的清楚。这使得函数运行速度更快,但同时就不允许用户使用可变参数了。

下面摘自《高质量程序设计第二版》的136页,对此的一个说明。
__cdecl:这是C+++/C函数的默认调用规范,参数从右到左依次传递并压入堆栈,用调用函数负责堆栈的清退,因此这种方式利于传递个数可变的参数给被调用函数(因为只有调用函数才知道它给被调用函数传递多少个参数及它们的类型)。如printf()就是这样的函数(函数的实现不需要知道实参的具体类型和个数)。
__stdcall:这是Win API函数使用的调用规范。参数从右到左依次传递并压入堆栈,用被调用函数负责堆栈的清退。该规范生成的函数代码比_cdecl更小,但当函数有可变个数的参数时会转为__cdecl规范。在windows中,宏WINAPI、CALLBACK都定义为__stdcall。
__thiscall:C++非静态成员函数的默认调用规范,不能使用个数可变的参数。当调用非静态成员函数的时候,this指针直接保存在ECX寄存器中而非压入函数堆栈。其他方面与_stdcall相同。
__fastcall:该规范所修饰的函数的实参将被直接传递到CPU寄存器中而不是内存堆栈中(这就是“快速调用”的含义)。堆栈清退由调用函数负责。该规范不能用于成员函数。
一般情况下我们不需要显示指定函数的调用规范。

No comments:

Post a Comment