<>指令前缀
<>地址大小与操作数的补充
*
8086CPU 有一个状态位决定操作数是 16 位还是 32 位。通过汇编和链接,设置改状态位为 1,则说明是 32 位操作数,否则是 16 位操作数。
*
使用前缀 0x66 来改变操作数的大小。
机器码:40 在 16 位中表示:inc ax 添加前缀后的机器码:66 40 在 32 位中表示:inc eax
在 16 位模式中使用前缀,则会修改为 32 位,若在 32 位模式中使用前缀,则会修改为 16 位,具有反转当前默认操作数大小的作用。
<>寄存器-寄存器/存储器模式(mod-reg-r/m)
mod-reg-r/m 字节对不同的指令有不同的使用。
三个域:
* 两位的 mod 域
* 三位的 reg 域
* 三位的 r/m 域
<>reg 域
操作码域本身已经有许多的指令,例如在 16 位模式中,机器码 40 对应操作为 inc ax,机器码只有一个字节,这很方便。
若是需要其它的例如 add、or、adc、sbb、and、sub、xor、cmp
等指令,它们后面都有一个在寄存器或存储器中的字节长的操作数和一个立即数,每条指令使用的操作码都为 80。那么选择这些指令中的哪一个便由 mod-reg-r/m
字节的 reg 域来决定了。
reg 域要满足:有且仅有一个操作数为寄存器或存储器,另外一个操作数必须是立即数。
对于操作码 80(这只是 12 个操作码中的一个),对应 reg 域为:
每一对操作数,若都不是立即数,则 8086 要求至少有一个操作数是寄存器。reg 域包含了该寄存器的编码。
<>mod 域
作用:确定操作数的类型。
通常,我们的指令类型:
* 两个操作数都是寄存器。
* 有一个操作数是寄存器,另一个操作数是存储器。
mod = 11: 表示该指令是一个寄存器到寄存器的操作,或一个立即数到寄存器的操作。
寄存器到寄存器:
* 目的寄存器在 reg 域中编码,而源寄存器在 r/m 域中编码。
* 使用者两个寄存器的编码如表 9-3 所示。
立即数到寄存器:
* 操作的编码如表 9-2 所示,目的寄存器在 r/m 域中编码。
若 mod 为其它值,则编码情况更复杂,它即取决于 mod 域又取决于 r/m 域。若 r/m = 100,则它还依赖于变址基址字节(SIB)。
<>SIB 域
SIB 字节由三个域组成:
* 一个两位的比例域
* 一个三位的变址寄存器域
* 一个三位的基址寄存器域
比例因子可在变址寄存器中写成整数形式。