据我所知,x64
代码有两种可能的调用约定 - Microsoft x64
和 AMD64
。
现在,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/