我想查看目标代码以获取某些指令以更好地理解它们。我对 modRM 字节的理解是,它对于寄存器到寄存器操作码
8A
(8 位)很有用,因为它用于确定目标和源寄存器/内存。
我的直觉让我相信 modRM 字节对于直接到内存来说并不是必需的,因为您需要的只是操作码、内存地址和硬编码值。 但是在调试 Visual Studio 时:
mov x, 100 ; x is byte length
目标代码是:
c6 05 xx xx xx xx 64
05
必须是这里的 modRM 字节。
我的问题是,它的意义是什么?为什么这里有必要?
它使编码更加一致...至少对于 x86 来说是“一致”。
指令需要编码内存地址。 Intel 决定在 8086 中将非寄存器指令编码为带有虚拟“reg”字段的 ModR/M 字节,而不是对不涉及寄存器的指令进行特殊的字节编码。 这样,相同的 ModR/M 解码逻辑将用于寄存器操作和非寄存器操作。 这个选择一直保留到现代 x86-64。
当没有寄存器字段时,ModR/M 字节的“reg”字段通常用作将多个操作编码为相同基本操作码的方式。 示例:
call rax ; FF D0
jmp rax ; FF E0
此处,“reg”字段对于间接
call
为 2,对于间接 jmp
为 4。 在 Intel 和 AMD 手册中,这分别表示为 FF /2
和 FF /4
:带有这些特定值“reg”的 ModR/M 字节。