我记得一段时间以前的一些规则(32位以前的英特尔处理器),当时很频繁(至少对我而言)必须分析C / C ++编译器生成的汇编输出(在我的例子中,Borland / Turbo at at那个时候)找到性能瓶颈,并安全地将程序集例程与C / C ++代码混合。比如使用SI寄存器作为 this 指针,AX用于返回值,当汇编例程返回时应该保留哪些寄存器等等。
现在我想知道是否有更多流行的C / C ++编译器(Visual C ++,GCC,Intel ......)和处理器(Intel,ARM,...)的参考,如果没有,在哪里可以找到碎片创造一个。想法?
答案 0 :(得分:11)
您正在询问“应用程序二进制接口”(ABI)和调用约定。这些通常由操作系统和库设置,并由编译器和链接器强制执行。 Google为“ABI”或“召集会议”。 Wikipedia和Debian for ARM的一些起点。
答案 1 :(得分:4)
Agner Fog的“呼叫约定”文档总结了Windows和Linux 64和32位ABI:http://www.agner.org/optimize/calling_conventions.pdf。有关寄存器使用的摘要,请参见第10页的表4。
个人经验中的一个警告:不要在内联汇编中嵌入关于ABI的假设。如果你在内联汇编中编写一个假定在特定寄存器中返回和/或参数传递的函数(例如eax,rdi,rsi),那么如果/当函数被编译器内联时,它将会中断。
答案 2 :(得分:1)
Open Watcom C / C ++编译器支持两种调用约定,基于寄存器(默认)和基于堆栈(非常接近其他编译器使用的)。该编译器的用户指南对它们进行了描述,并且与编译器online一起免费提供itself。您可以在“用户指南”中找到这些主题,特别有用:
答案 3 :(得分:0)
好吧,今天如果打开优化,就没有了。但GCC允许您声明汇编指令应该使用特定变量,无论它是否在寄存器中,或者甚至强制GCC tu将该变量放入可用于您的指令的寄存器中。您还可以声明内联汇编块为自己保留哪些寄存器(因此,如果需要,编译器应在您的内联片段周围生成适当的保存/恢复代码)
答案 4 :(得分:0)
我相信但是我不确定GCC是否使用Itanium ABI来完成其大部分功能;它与它使用的ABI之间的不兼容性是documented。