【发布时间】:2014-12-31 00:21:46
【问题描述】:
回想一下,x86 架构将 0x0F 0x1F [mod R/M] 定义为多字节 NOP。
现在我正在查看 8 字节 NOP 的具体情况:我有
0x0F 0x1F 0x84 0x__ 0x__ 0x__ 0x__ 0x__
最后 5 个字节有任意值。
第三个字节[mod R/M],拆分后给出:
-
mod = 10b: 参数是reg1+ 一个 DWORD 大小的位移 -
reg2 = 000b:(我们不在乎) -
reg1 = 100b:表示参数是SIB字节 + DWORD 大小的位移。
现在,作为一个具体的例子,如果我采取
0x0F 0x1F 0x84 0x12 0x34 0x56 0x78 0x9A
我有
SIB = 0x12-
displacement = 0x9A785634:一个双字
现在我添加 0x66 指令前缀,表示位移应该是 WORD 而不是 DWORD:
0x66 0x0F 0x1F 0x84 0x12 0x34 0x56 0x78 0x9A
我希望0x78 0x9A 被“切断”并被视为新指令。但是,当编译它并在生成的可执行文件上运行 objdump 时,它仍然使用所有 4 个字节(一个 DWORD)作为位移。
我在这种情况下是否误解了“位移”的含义?还是0x66前缀对多字节NOP指令没有影响?
【问题讨论】:
-
0x66 前缀不影响位移的大小——只影响操作数大小。
-
那么,如果一条指令的组成部分是:Prefix、Opcode、Mod R/M、SIB、Displacement、Immediate,那么 0x66 会影响 Immediate 的值吗?好吧,这有点道理:多字节 NOP 不采用立即值,因此 0x66 没有任何效果。谢谢!