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手册告诉我们ff
是JMP
的操作码,而最后四个字节显然是目标地址。在对 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 rm32
、dec rm32
、call rm32
、call m16:32
、jmp m16:m32
、push 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。
考虑以下代码,使用 gcc 4.8.2
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手册告诉我们ff
是JMP
的操作码,而最后四个字节显然是目标地址。在对 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 rm32
、dec rm32
、call rm32
、call m16:32
、jmp m16:m32
、push 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。