C++支持多种调用约定,这些约定定义了函数参数如何被传递以及谁负责清理栈帧。以下是C++中常见的调用约定:
-
cdecl(C Declaration):
- 参数从右到左依次压入栈中。
- 调用者负责清理栈帧,即释放所有通过
push
压入的参数。 - 支持可变参数列表。
- 在Windows平台上广泛使用,例如
printf
和scanf
。
-
stdcall(Standard Call):
- 参数也是从右到左压入栈中。
- 被调用的函数负责清理栈帧。
- 支持可变参数列表。
- 参数必须通过寄存器传递(除了最后一个固定参数外)。
- 在Windows平台上,API函数通常使用
stdcall
调用约定。
-
fastcall(Fast Call):
- 参数从左到右依次压入栈中,但第一个整数或指针参数通过
ECX
寄存器传递,第二个参数通过EDX
寄存器传递,其余参数通过栈传递。 - 被调用的函数负责清理栈帧。
- 适用于需要快速调用的情况。
- 在Windows平台上较为常见。
- 参数从左到右依次压入栈中,但第一个整数或指针参数通过
-
thiscall(This Call):
- 主要用于成员函数调用。
this
指针作为隐藏的第一个参数通过ECX
寄存器传递。- 其他参数通过栈传递。
- 在C++对象的方法调用中使用。
-
vectorcall:
- 由Intel编译器引入,用于优化具有多个参数的函数调用。
- 参数通过一组寄存器传递,具体寄存器取决于编译器和目标架构。
- 可以提高参数传递的效率。
-
ms64call(Microsoft 64-bit Call):
- 在64位Windows平台上使用。
- 支持更多的寄存器用于参数传递,提高了性能。
- 与
stdcall
类似,但使用了不同的寄存器集合。
了解这些调用约定对于编写可移植、高效且易于维护的C++代码至关重要。在实际编程中,应根据具体情况选择合适的调用约定,并确保与调用者和被调用者的一致性。