Gcc x64 函数调用
据我所知,x64
代码有两种可能的调用约定 - Microsoft x64
和 AMD64
。
现在,可以使用 -mregparm=0
参数启动 gcc
,但如果我们使用 AMD64
调用约定,则该参数不起作用。 发生这种情况是因为 AMD64
约定要求前 6 个变量使用寄存器(我不太确定为什么这样做,但我怀疑它是由于执行而实现的)可能存在堆栈安全问题)。
所以,问题来了:
在Microsoft x64下使用
gcc
编译时,是否有一些像这样的严格规则(强制寄存器使用)约定?如果是的话,如何在不破坏 ABI
兼容性的情况下绕过它们?
As far as I know, there are two possible calling conventions for the x64
code - Microsoft x64
and AMD64
.
Now, gcc
can be launched with the -mregparm=0
parameter, which doesn't work if we are working using the AMD64
calling convention. This happens because the AMD64
convention mandates the usage of the registers for the first 6 variables (I'm not really sure why this is done, but I suspect it's implemented due do possibly stack security issues).
So, here is the question:
Are there some strict rules like this (forced register usage) when compiling using gcc
under Microsoft x64
convention? And, if yes, how can they be bypassed without breaking the ABI
compatibility?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不了解 Microsoft Windows(也从未使用过它),因此我可能无法回答您的问题。
但是,AMD64 应用程序二进制接口调用约定(在 Linux 和其他 Unix 上)记录在 AMD64 ABI 规范中 (也许您还应该查找并阅读 Microsoft 调用约定的等效文档)。我相信他们使用寄存器作为前 6 个参数是出于性能考虑(通过寄存器传递值比在堆栈上传递值更快),而不是出于安全考虑。
无论您使用什么 C++ 编译器,您都希望它遵循一些调用约定,而这些约定实际上是由系统决定的(因为您希望能够从代码中调用系统库)。因此,如果破坏它们,就会破坏 ABI 兼容性。
但我无法猜测为什么要问这样的问题。您是否正在开发具有自己的调用约定的编译器?如果是,您仍然应该有一些方法来调用 C 库,这要求调用外部 C 库时,您遵循管理它们的 ABI 约定。查看 Ocaml 编译器的示例。
I don't know Microsoft Windows (and never used it), so I probably cannot answer your question about it.
However, the AMD64 Application Binary Interface calling conventions (On Linux and other Unixes) are documented in the AMD64 ABI spec (maybe you should also find and read the equivalent document for Microsoft calling conventions). I believe they are using registers for the 6 first arguments because of performance considerations (passing values thru register is faster than passing them on the stack), not because of security considerations.
And whatever C++ compiler you use, you want it to follow some calling conventions, and these are practically dictated by the system (because you want to be able to call system libraries from your code). So if you break them, you will break the ABI compatibility.
But I cannot guess why are asking such a question. Are you developing a compiler with its own calling conventions? If yes, you still should have some means to call C libraries, and this required that for call to external C libraries, you follow the ABI conventions governing them. Look into the Ocaml compiler for an example.
我认为你无法在不破坏 ABI 的情况下绕过这些。函数调用及其如何影响寄存器等是平台 ABI 的基本部分。
由于函数调用 ABI 不匹配,您的程序可能无法在 Windows x64 上运行。
有关您可能需要的所有文档,请参阅此 MSDN链接
I don't think you can bypass these without breaking ABI. A function call and how that affects registers etc. is a fundamental part of the platform ABI.
Chances are your program will not work on Windows x64 due to a mismatched function call ABI.
For all the documentation you could want, see this MSDN link