英特尔语法:mov eax, 1(指令目标,源)
AT&T 语法:movl $1, %eax(指令源,目标)
Intel 的语法很容易解释。在上面的示例中,移动的数据量是根据寄存器的大小(在 eax 的情况下为 32 位)推断出来的。使用的寻址模式是从操作数本身推断出来的。
AT&T 语法有一些怪癖。首先,注意指令l
末尾的后缀mov
,它代表long
并表示 32 位数据。其他指令后缀包括
w
一个字(16 位 -不要与 CPU 的字长混淆!)、q
一个四字(64 位)和b
一个单字节。虽然并不总是需要,但通常您会看到使用 AT&T 语法的汇编代码明确说明指令正在操作的数据量。
当涉及到源操作数和目标操作数上使用的寻址模式时,需要更加明确。$
表示immediate
寻址,就像使用指令本身中的值一样。在上面的例子中,如果没有 this 写入$
,direct
将使用寻址,即 CPU 将尝试获取内存地址 1 处的值(这很可能会导致分段错误)。%
表示register
寻址,如果您没有在上面的示例中包含它,将eax
被视为一个symbol
即标记的内存地址,这很可能会导致undefined reference
链接时间。因此,您必须明确说明两者使用的寻址模式源操作数和目标操作数。
指定内存操作数的方式也不同:
英特尔:[基址寄存器 + 索引 * 索引大小 + 偏移量]
AT&T:偏移量(基址寄存器、索引、索引大小)
英特尔语法使查找内存地址的计算更加清晰。使用 AT&T 语法,结果是相同的,但您应该知道正在发生的计算。
至少理论上应该产生相同的二进制文件
这完全取决于您的工具链。
偏爱其中一个的原因是什么?
当然,个人偏好,在我看来,这归结为在寻址内存时您感觉更舒服的语法。你更喜欢 AT&T 语法的强制明确性吗?或者你更喜欢你的汇编程序为你找出这个低级细节?
是命令行选项吗?宏?非助记词?
这与汇编程序(GAS、NASM)本身有关。再次,个人喜好。