Mod R/M 字节为无条件跳转指令 0xFF 携带什么含义(如果有)?

What meaning, if any, does the Mod R/M byte carry for the unconditional jump instruction 0xFF?

考虑以下代码,使用 gcc 4.8.2

在 32 位 Ubuntu 14.04.2 上编译
#include <unistd.h>

int main(){
    _exit(0);
}

如果我在 gdb 和 运行 disas /r _exit 中打开此代码,我会得到以下内容。

(gdb) disas /r _exit
Dump of assembler code for function _exit@plt:
   0x080482f0 <+0>:     ff 25 0c a0 04 08       jmp    *0x804a00c
   0x080482f6 <+6>:     68 00 00 00 00  push   [=13=]x0
   0x080482fb <+11>:    e9 e0 ff ff ff  jmp    0x80482e0
End of assembler dump.
(gdb)

Intel手册告诉我们ffJMP的操作码,而最后四个字节显然是目标地址。在对 Intel 指令的结构进行一些研究后,25 似乎是一个 Mod R/M 字节,但我找不到 Mod R/M 字节相对于 [=19] 应该如何解释=] 指令.

我已经阅读了 general interpretation of the Mod R/M byte,但我不明白字节 0x25 在上面 disas 输出中的具体含义。

这里0x25的具体含义是什么,Mod R/M字节相对于JMP的一般解释是什么?

实际上,最后4个字节不是目标地址。 ff 25 0c a0 04 08指令是jmp rm32的一个实例(绝对间接跳转),最后4个字节实际上是将要读取跳转目标的地址。

如您在 this table 中所见,ModRM 字节 25h 的 /digit 部分为 4(这使其成为 jmp rm32,其他具有操作码字节 ff 的指令分别是 inc rm32dec rm32call rm32call m16:32jmp m16:m32push rm32,均由 ModRM 字节区分)。 ModRM 字节的其余部分 25h 表示操作数是 [sdword].

形式的内存地址

对于操作码 0xFF,MODRM 字节的含义与使用 MODRM 字节的任何其他指令的含义相同。

最好的参考资料是在线 Intel Instruction set manuals。第 2 节和 JMP 指令页面是您需要为此操作码正确解释 MODRM 位的内容。

“0x25”的解释是:

  • (位 7-6)MOD = 二进制 00
  • (位 5-3)Reg/Opcode = 二进制 100
  • (位 2-0)R/M = 二进制 101

MOD=00 和 R/M = 二进制 101 表示 "use disp32"(32 位地址)跟在 MODRM 字节之后。 MODRM 字节后的 32 位偏移量是内存位置。您可以看到它与调试列表中反汇编的 jmp 指令中的值匹配。

您可能对操作码 0xFF 的含义感到困惑;它并不一定意味着 "JMP"。 x86经常使用MODRM Reg/Opcode位来修改操作码字节的含义,以挑选出特定的指令[=39] =].

对于操作码 0xFF,Reg/Opcode 位被解释为 更多操作码 位:

  • Reg/Opcode bits = binary 100(Intel手册中写为“/4”)选择指令"jmp near absolute indirect"。 x86 有所谓的段寄存器,包括 CS; "jmp near" 在这种情况下表示 "don't load CS"。
  • Reg/Opcode == 101 ("/5") 表示 "jmp far"(加载 CS)并且不在现代实践中使用。
  • Reg/Opcode 具有其他值指定的指令不是 JMP。