我想写一个小的底层程序。对于它的某些部分,我将需要使用汇编语言,但其余代码将使用 C/C++ 编写。
那么,如果我要使用 GCC 将 C/C++ 与汇编代码混合,我需要使用 AT&T 语法还是可以 我使用英特尔语法?或者如何以其他方式混合 C/C++ 和 asm(intel 语法)?
我意识到也许我别无选择,必须使用 AT&T 语法,但我想确定..
如果事实证明别无选择,我在哪里可以找到有关 AT&T 语法的完整/官方文档?
谢谢!
最佳答案
如果您使用单独的汇编文件,gas 有一个指令来支持 Intel 语法:
.intel_syntax noprefix # not recommended for inline asm
它使用 Intel 语法并且在寄存器名称之前不需要 % 前缀。
(您还可以使用 -msyntax=intel -mnaked-reg
运行 as
以将其作为默认值而不是 att
,在如果您不想将 .intel_syntax noprefix
放在文件的顶部。)
内联汇编:使用-masm=intel
编译
对于内联汇编,您可以使用 gcc -masm=intel
编译您的 C/C++ 源代码(详情请参阅 How to set gcc to use intel syntax permanently?。)编译器自己的 asm 输出(内联 asm 插入其中)将使用 Intel 语法,并且它将使用 Intel 语法将操作数替换为 asm 模板字符串,例如 [rdi + 8]
而不是 8(%rdi)
.
这适用于 GCC 本身和 ICC,但仅适用于 clang clang 14 and later .
(尚未发布,但补丁在当前主干中。)
在内联 asm 的开头使用 .intel_syntax noprefix
,然后切换回 .att_syntax
可以工作,但如果您使用 会中断任何 m
约束。内存引用仍将以 AT&T 语法生成。它恰好适用于寄存器,因为即使在 intel-noprefix 模式下,GAS 也接受 %eax
作为寄存器名称。
在 asm()
语句末尾使用 .att_syntax
也会破坏 -masm=intel
的编译;在那种情况下,GCC 自己的 asm 在您的模板之后(和之前)将采用 Intel 语法。 (Clang 没有那个“问题”;每个 asm 模板字符串都是本地的,这与 GCC 不同,GCC 模板字符串真正成为 GCC 发送到 as
的文本文件的一部分以单独组装。)
相关:
- GCC manual: asm dialect alternatives : 用
{att | 编写一个
,因此它在使用asm
语句intel}-masm=att
或-masm=intel
编译时可以正常工作。参见 an example使用lock cmpxchg
。 - https://stackoverflow.com/tags/inline-assembly/info有关一般内联汇编的更多信息;确保您向编译器准确描述您的 asm 非常重要,这样它就知道读取/写入了哪些寄存器和内存。
- AT&T 语法:https://stackoverflow.com/tags/att/info
- 英特尔语法:https://stackoverflow.com/tags/intel-syntax/info
- x86 tag wiki包含指向手册、优化指南和教程的链接。
关于我可以将 Intel 语法的 x86 程序集与 GCC 一起使用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26129497/