【发布时间】:2018-02-27 05:12:00
【问题描述】:
从英特尔软件开发人员手册(在本文中称为 ISDM)和 x86 Instruction Set Reference(我假设它只是前者的副本),我们知道 mov 指令可以从eax/ax/al 到内存偏移量,反之亦然。
例如,mov moffs8, al 将al 寄存器的内容移动到某个8 位 内存偏移量moffs8。
现在,moffs8 是什么?引用 ISDM (3.1.1.3):
moffs8、moffs16、moffs32、moffs64 — MOV 指令的某些变体使用的字节、字或双字类型的简单内存变量(内存偏移)。实际地址由相对于段基的简单偏移量给出。指令中没有使用 ModR/M 字节。
moffs显示的数字表示它的大小,由指令的address-size属性决定。
我强调了moffs8的类型是byte并且大小为8位的句子。
我是一个汇编初学者,所以,在阅读完这篇文章后,我立即开始使用 NASM 玩弄 mov moffs8, al 指令。这是我写的代码:
; File name: mov_8_bit_al.s
USE32
section .text
mov BYTE [data], al
section .bss
data resb 2
这是nasm -f bin mov_8_bit_al.s 产生的(十六进制):
A2 08 00 00 00
我是这样理解的:
-
A2是MOV moffs8, AL的操作码 -
08是内存偏移量本身,大小为 1 字节 -
00 00 00有点垃圾
看起来08 00 00 00 是内存偏移量,但在这种情况下,它是moffs32,而不是moffs8!因此,CPU 在执行A2 时将只读取一个字节,并将00 视为ADD 指令或其他内容,这不是预期的。
目前,在我看来,NASM 在这里生成了无效的字节码,但我想是我误解了一些东西……也许 NASM 不遵循 IDSM?如果是这样,它的代码将无法在 Intel CPU 上正确执行,所以它应该遵循它!
你能解释一下我哪里错了吗?
【问题讨论】: