4

我记得以前的一些规则(32 位之前的英特尔处理器),当时(至少对我而言)非常频繁地必须分析 C/C++ 编译器(在我的情况下,当时是 Borland/Turbo)生成的汇编输出找到性能瓶颈,并安全地将汇编程序与 C/C++ 代码混合。诸如将 SI 寄存器用于this指针、将 AX 用于返回值、在汇编例程返回时应保留哪些寄存器等。

现在我想知道是否有更流行的 C/C++ 编译器(Visual C++、GCC、Intel ...)和处理器(Intel、ARM、...)的参考,如果没有,在哪里可以找到要创建的部分一。想法?

4

5 回答 5

11

您正在询问“应用程序二进制接口”(ABI)和调用约定。这些通常由操作系统和库设置,并由编译器和链接器强制执行。谷歌为“ABI”或“调用约定”。来自WikipediaDebian for ARM 的一些起点。

于 2008-11-01T23:43:41.117 回答
4

Agner Fog 的“调用约定”文档总结了 Windows 和 Linux 64 位和 32 位 ABI 等内容:http ://www.agner.org/optimize/calling_conventions.pdf 。请参阅第 10 页上的表 4,了解寄存器使用的摘要。

来自个人经验的一个警告:不要将关于 ABI 的假设嵌入到内联汇编中。如果您在内联汇编中编写一个函数,假设返回和/或参数在特定寄存器(例如eax、rdi、rsi)中传输,那么如果/当编译器内联该函数时,它将中断。

于 2012-08-07T21:35:06.137 回答
1

Open Watcom C/C++ 编译器支持两种调用约定,基于寄存器(默认)和基于堆栈(非常接近其他编译器使用的)。此编译器的用户指南对它们都进行了描述,并且与编译器本身一起可在线免费获得。您可能会发现用户指南中的这些主题特别有用:

  • 10.4.1 使用基于寄存器的调用约定传递参数
  • 10.4.6 使用基于堆栈的调用约定
  • 10.5 基于 80x87 的应用程序的调用约定
于 2008-11-03T10:05:44.447 回答
0

好吧,今天如果打开优化,就没有了。但是 GCC 允许你声明你的汇编指令应该使用特定的变量,无论它是否在寄存器中,或者甚至强制 GCC tu 将该变量放入可与你的指令一起使用的寄存器中。您还可以声明哪些注册您的内联汇编块为自己保留(因此如果需要,编译器应该在您的内联块周围生成适当的保存/恢复代码)

于 2008-11-01T23:47:08.003 回答
0

我相信但绝不肯定 GCC 使用Itanium ABI来完成其大部分功能。它和它使用的 ABI 之间的不兼容性被记录在案

于 2008-11-02T00:11:51.260 回答