考虑下面的代码,在32位编译Ubuntu 14.04.2与gcc 4.8.2
#include <unistd.h>
int main(){
_exit(0);
}
Run Code Online (Sandbox Code Playgroud)
如果我打开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 $0x0
0x080482fb <+11>: e9 e0 ff ff ff jmp 0x80482e0
End of assembler dump.
(gdb)
Run Code Online (Sandbox Code Playgroud)
英特尔手册告诉我们这ff是操作码JMP,而后四个字节显然是目标地址.在对Intel指令的结构进行一些研究之后,25看起来是一个Mod R/M字节,但是我找不到如何Mod R/M根据JMP指令解释该字节.
我已经阅读了Mod R/M字节的一般解释,但我不明白字节0x25在disas上面的输出中具有什么特定含义.
0x25这里具体含义是什么,Mod R/M字节的一般解释是JMP什么?
Ira*_*ter 10
对于操作码0xFF,MODRM字节的含义与使用MODRM字节的任何其他指令的含义相同.
您最好的参考是在线英特尔指令集手册.第2节和JMP指令页面是您正确解释此操作码的MODRM位所需的页面.
"0x25"的解释是:
MOD = 00和R/M =二进制101表示MODRM字节之后的"use disp32"(32位地址).MODRM字节后面的32位偏移是存储单元.您可以看到它与调试列表中反汇编的jmp指令中的值匹配.
您可能会对操作码0xFF的含义感到困惑; 它并不一定意味着"JMP".x86通常使用MODRM Reg/Opcode位来修改操作码字节的含义,以选择特定指令.
使用操作码0xFF,Reg/Opcode位被解释为更多的操作码位: