c++ - Gcc x64 函数调用

标签 c++ gcc 64-bit convention abi

据我所知,x64 代码有两种可能的调用约定 - Microsoft x64AMD64

现在,gcc 可以使用 -mregparm=0 参数启动,如果我们使用 AMD64 则该参数不起作用调用约定。 发生这种情况是因为 AMD64 约定要求对前 6 个变量使用寄存器(我不太确定为什么这样做,但我怀疑它的实现是由于可能是堆栈安全问题)。

那么,问题来了:

Microsoft x64 约定下使用 gcc 进行编译时,是否有像这样的严格规则(强制使用寄存器)?而且,如果是,如何在不破坏 ABI 兼容性的情况下绕过它们?

最佳答案

我不了解 Microsoft Windows(也从未使用过),所以我可能无法回答您的相关问题。

但是,AMD64 应用程序二进制接口(interface)调用约定(在 Linux 和其他 Unix 上)记录在 AMD64 ABI spec 中(也许您还应该找到并阅读 Microsoft 调用约定的等效文档)。我相信他们为 6 个第一个参数使用寄存器是出于性能考虑(通过寄存器传递值比在堆栈上传递值更快),而不是出于安全考虑。

无论您使用什么 C++ 编译器,您都希望它遵循一些调用约定,而这些约定实际上是由系统规定的(因为您希望能够从您的代码中调用系统库)。因此,如果您破坏它们,就会破坏 ABI 兼容性。

但我猜不出为什么要问这样的问题。您正在开发具有自己的调用约定的编译器吗?如果是,您仍然应该有一些方法来调用 C 库,这要求调用外部 C 库,您遵循管理它们的 ABI 约定。查看 Ocaml 编译器的示例。

关于c++ - Gcc x64 函数调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7902903/

相关文章:

c++ - 使用后丢弃 DLL 的资源

c++ - vector 子集的迭代器

c# - Any CPU dependent on C++/CLI dependent on native C dll (any cpu for c++/cli)

.net - 我如何知道给定类型的 .net 数组可以分配的实际最大元素数?

c++ - 组合的快速排名/取消排名(64 位)

c++ - 如何在QScrollArea上绘制QImage?这样做了,但是有一些小问题 QPainter::begin: Widget painting can only begin as a result of a paintEvent

c++ - g++ 中的显式模板特化导致麻烦

C++:没有断点工作

c++ - 如何确定可以传递给编译器选项的最小值和最大值?

c++ - C++ 宏中的语句