assembly - 16 位汇编:不能取消引用某些寄存器
问题描述
我正在尝试以下英特尔 16 位指令:
mov si, word [reg]
reg
一些寄存器在哪里。如果reg
is编译得很好bx
,但是当它是ax
, cx
or时不能编译dx
。我正在使用 NASM 作为我的汇编程序。我确信这是由于指令集中的一些限制。有人可以解释一下限制和背后的理由吗?
解决方案
只有以下变址寄存器可用于 16 位寻址模式:
bx
si
di
bp
bx + si
bx + di
bp + si
bp + di
同样,SIB 寻址不适用于 16 位寻址模式。
如果您想使用其他变址寄存器,您始终可以使用 32 位寻址模式,例如[eax]
. 只要您在 80386 或更新的处理器上运行您的代码,它就可以工作。
存在此限制是因为 modr/m 字节只有三个位用于(索引)寄存器。正如您在上面看到的,恰好存在 8 种可能的变址寄存器组合。我不知道他们为什么将寻址模式设计成这样,但对于 70 年代的 16 位处理器来说,这听起来很合理,就像 8086 一样。
在 32 位模式和长模式下,此方案已更改,因此 8 个可能的索引寄存器中有 7 个指代 eax、ebx、ecx、edx、esi、edi 和 ebp,而指代 esp 的内容则表示存在 sib 字节允许众所周知的[base+index*scale]
寻址模式。
推荐阅读
- c++ - `vaddhn_high_s16` 实际上做了什么?
- python - 在列表中使用索引时遇到问题
- javascript - 将具有重复值的对象组合在数组中
- android - 不能在 CardView 中设置 RecyclerView?
- sql - 如何在具有完全非结构化字符串列的任何表的任何列上的任何匹配字符上加入多个表?
- supervisord - 达芙妮在主管下不断退出,没有任何错误
- javascript - Google Apps 脚本:错误 400:错误请求:组发送失败
- python - 如何使用numpy加上一个martix中的每一行以及另一个martix中的每一行
- javascript - 在画布面料js上添加图像(按路径)
- docker - 我怎样才能让赛普拉斯在 CI 中访问除 root 之外的其他路由?