首页 > 解决方案 > 当操作符宽度与寄存器宽度不匹配时,AT&T 汇编器的行为如何?

问题描述

我正在对 x86 汇编器进行一些研究,并遇到了这篇维基百科文章

它指出,英特尔语法汇编器从寄存器宽度推断指令/操作数的宽度。

AT&T 语法汇编助记符在“基本”助记符后面加上一个字母,以指定操作数的宽度。与 Intel 语法一样,寄存器宽度仍然可以由寄存器名称指定。

例如ax寄存器是 16 位宽,eax寄存器是 32 位宽。

在 Intel 语法中,mov指令宽度是从寄存器的宽度推断出来的。

在 AT&T 中,movl是对 32 位宽数据进行操作的指令,mov(?) 对 16 位宽数据进行操作。(至少这是我的猜测——我之前没有在 AT&T 写过任何东西。)

我的问题是,如果寄存器和运算符宽度不同,在 AT&T 语法汇编代码中,并且尝试编译它,会发生什么?运算符宽度优先,还是这只是一个错误,汇编代码不会汇编?

标签: assemblyx86att

解决方案


汇编是汇编的,而不是编译的,因此“不编译”通常适用于汇编。

但是,是的,一般来说,大小后缀不匹配会导致汇编器拒绝您的代码并显示一些错误消息。通常,此错误消息很有帮助,但有时它也可能具有误导性。使用编写不佳的汇编程序,可能会产生其他结果,包括无意义的结果。例如,某些版本的 DOSDEBUG.COM汇编

PUSH BYTE AL

进入一个无效指令,尽管它不存在,但它在逻辑上是对该指令进行编码的结果。然而,现代汇编程序通常不会以这种方式行为不端(尽管汇编程序错误并非闻所未闻)。

另请注意,在某些情况下,允许看似不匹配的指令大小。例如,允许写

movl %ds, %eax

尽管前者是一个 16 位寄存器。这是因为 CPU 确实支持这种操作,其操作数大小为 32 位,零扩展%ds%eax.


推荐阅读