assembly - 当操作符宽度与寄存器宽度不匹配时,AT&T 汇编器的行为如何?
问题描述
我正在对 x86 汇编器进行一些研究,并遇到了这篇维基百科文章。
它指出,英特尔语法汇编器从寄存器宽度推断指令/操作数的宽度。
AT&T 语法汇编助记符在“基本”助记符后面加上一个字母,以指定操作数的宽度。与 Intel 语法一样,寄存器宽度仍然可以由寄存器名称指定。
例如ax
寄存器是 16 位宽,eax
寄存器是 32 位宽。
在 Intel 语法中,mov
指令宽度是从寄存器的宽度推断出来的。
在 AT&T 中,movl
是对 32 位宽数据进行操作的指令,mov
(?) 对 16 位宽数据进行操作。(至少这是我的猜测——我之前没有在 AT&T 写过任何东西。)
我的问题是,如果寄存器和运算符宽度不同,在 AT&T 语法汇编代码中,并且尝试编译它,会发生什么?运算符宽度优先,还是这只是一个错误,汇编代码不会汇编?
解决方案
汇编是汇编的,而不是编译的,因此“不编译”通常适用于汇编。
但是,是的,一般来说,大小后缀不匹配会导致汇编器拒绝您的代码并显示一些错误消息。通常,此错误消息很有帮助,但有时它也可能具有误导性。使用编写不佳的汇编程序,可能会产生其他结果,包括无意义的结果。例如,某些版本的 DOSDEBUG.COM
汇编
PUSH BYTE AL
进入一个无效指令,尽管它不存在,但它在逻辑上是对该指令进行编码的结果。然而,现代汇编程序通常不会以这种方式行为不端(尽管汇编程序错误并非闻所未闻)。
另请注意,在某些情况下,允许看似不匹配的指令大小。例如,允许写
movl %ds, %eax
尽管前者是一个 16 位寄存器。这是因为 CPU 确实支持这种操作,其操作数大小为 32 位,零扩展%ds
为%eax
.
推荐阅读
- kubernetes - 在 Kubernetes 中注入 volumeMount
- angular - 无法拖动垫滑块
- android - 在使用 agora.io 的视频通话中按下主页按钮时调用 onDestroy()
- javascript - 如何在 VS Code 中使用 Libman json 文件?
- html - 使表单输入正确浮动
- php - CodeIgniter:IP 地址与域名上的 CSS 样式被破坏
- neo4j - 将两个不同列的查询结果合二为一
- javascript - 在 SocketIO 事件侦听器中调用 setState 后,React 组件未更新
- javascript - 在 onclick JavaScript 函数中使用 html 输入作为参数?
- python - IndentationError:使用异常期望缩进块