为什么 NOP 在 x86 汇编中分配给 0x90?
Why was NOP assigned to 0x90 in x86 assembly?
为什么在英特尔 x86 汇编上将 nop
分配给 0x90
?
直觉上我希望 0x00
会映射到 nop
(在英特尔 x86 上也是 xchg eax, eax
),就像 ARM A32
和其他一些情况一样架构。
0x00000000 在 ARM A32 上实际上不是 NOP,尽管它表现得像一个;它实际上是 andeq r0, r0, r0
而真正的 NOP 是 0xe1a00000
(mov r0, r0)。让 NUL 字节成为 NOP 是一个相当糟糕的主意,因为这会使每个空内存区域成为一个空闲的 NOP 幻灯片,从而大大增加了攻击的风险。现代架构通常试图让全零成为中断指令或类似指令以避免这种攻击向量。例如,ARM A64 使 0x00000000
成为永久未定义的指令 udf 0
.
0x90
实际上只是 0x90 + r
操作码家族的一条指令,代表 xchg r32, eax
。 eax
是寄存器 0,所以 0x90
代表 xchg eax, eax
这是一个 NOP。在长模式下,0x90
是特殊情况,不会将 rax
的高 32 位清零以保持其作为单字节 NOP 的功能。
为什么在英特尔 x86 汇编上将 nop
分配给 0x90
?
直觉上我希望 0x00
会映射到 nop
(在英特尔 x86 上也是 xchg eax, eax
),就像 ARM A32
和其他一些情况一样架构。
0x00000000 在 ARM A32 上实际上不是 NOP,尽管它表现得像一个;它实际上是 andeq r0, r0, r0
而真正的 NOP 是 0xe1a00000
(mov r0, r0)。让 NUL 字节成为 NOP 是一个相当糟糕的主意,因为这会使每个空内存区域成为一个空闲的 NOP 幻灯片,从而大大增加了攻击的风险。现代架构通常试图让全零成为中断指令或类似指令以避免这种攻击向量。例如,ARM A64 使 0x00000000
成为永久未定义的指令 udf 0
.
0x90
实际上只是 0x90 + r
操作码家族的一条指令,代表 xchg r32, eax
。 eax
是寄存器 0,所以 0x90
代表 xchg eax, eax
这是一个 NOP。在长模式下,0x90
是特殊情况,不会将 rax
的高 32 位清零以保持其作为单字节 NOP 的功能。