C++函数的调用约定
引入
调用约定允许你指定被调函数和调用者之间传递参数和返回值的方式。不同的调用约定区别主要在于:
- 参数和返回值放置的位置。
- 参数传递的顺序。
- 调用前设置和调用后清理的工作,在调用者和被调用者之间如何分配。
并非所有约定都在所有支持的平台上可用,某些约定使用平台特定的实现。这篇文章描述的是Windows x86平台。
在 x86 平台上,所有参数在传递时都将加宽到 32 位。 返回值也将加宽到 32 位,并通过 EAX 寄存器返回。8字节的结构是一个例外,它通过EDX:EAX寄存器对返回。更大的结构将在 EAX 寄存器中作为指向被隐藏的返回结构的指针返回。
如图所示(使用VS 2019的调试功能,并非实际的汇编代码):
常见的调用约定
关键字 | 堆栈清理 | 参数传递 |
---|---|---|
__cdecl | 调用方 | 在堆栈上按相反顺序推送参数(从右到左) |
__stdcall | 被调用方 | 在堆栈上按相反顺序推送参数(从右到左) |
__fastcall | 被调用方 | 存储在寄存器中,然 |