了解 C/C 中的各种调用约定
C/C 提供了一系列调用约定,每个调用约定都有不同的特征和含义用于函数调用。这些约定决定如何将参数传递给函数以及如何处理返回值。
可用的调用约定
C/C 中可用的主要调用约定是:
-
cdecl: 参数被压入堆栈从右到左,包含被调用者保存的寄存器(EAX、ECX、EDX)和调用者保存的寄存器(堆栈指针和其余寄存器)。
-
syscall: 与 cdecl 类似,但是不保留 EAX、ECX 和 EDX。参数列表大小在 AL 中传递。
-
pascal: 参数从左到右压入堆栈,被调用者负责堆栈平衡。
-
stdcall: pascal 的变体,其中被调用者负责堆栈清理,但参数被推送到堆栈上从右到左。 EAX、ECX 和 EDX 指定在函数内使用。
-
fastcall: 将前两个参数传递到 ECX 和 EDX 寄存器,并将剩余参数从右到左传递到堆栈.
扩展通话约定
除了这些标准约定之外,还有一些专门的变体:
-
向量调用:使用SIMD寄存器传递向量参数,扩展对传递的支持同质向量聚合值。
-
safecall: 封装 COM 错误处理,异常在 EAX 中作为 HResult 传回,结果通过堆栈上的引用传递。
-
Microsoft X64 调用约定: 对整数和浮点参数使用特定寄存器,并将其他参数推送到堆栈。调用者负责在堆栈上分配“影子空间”。
选择正确的约定
适当的调用约定取决于特定的平台、编译器,以及申请要求。选择调用约定时要考虑参数数量、寄存器使用情况和性能优化等因素。
例如,stdcall 常用于调用 Windows API 函数,而 cdecl 常用于类 Unix 环境。 fastcall 可以为参数较少的函数提供更快的性能。
其他资源
- [Microsoft 文档:调用约定](https://docs.microsoft.com) com/en-us/cpp/build/x64-calling-convention)
- [维基百科:调用约定](https://en.wikipedia.org/wiki/Calling_convention)
以上是不同的调用约定如何影响 C/C 中的函数调用?的详细内容。更多信息请关注PHP中文网其他相关文章!