1

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

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

所以,这里有一个问题:

在按照约定编译使用时是否有一些像这样的严格规则(强制寄存器使用)?而且,如果是,如何在不破坏兼容性的情况下绕过它们?gccMicrosoft x64ABI

4

2 回答 2

3

我认为你不能在不破坏 ABI 的情况下绕过这些。函数调用以及它如何影响寄存器等是平台 ABI 的基本部分。

由于函数调用 ABI 不匹配,您的程序可能无法在 Windows x64 上运行。

有关您可能需要的所有文档,请参阅此 MSDN 链接

于 2011-10-26T12:59:39.710 回答
3

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

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

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

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

于 2011-10-26T13:07:42.497 回答