Hri*_*ali 4 x86 instruction-set opcode disassembly x87
在我尝试为x86平台上的32位Linux编写反汇编程序时,我遇到了一个问题.当我使用以下方法拆卸简单的ELF-32可执行文件时,我看到了以下操作码序列objdump:
dc 82 04 08 0d 00 faddl 0xd0804(%edx)
Run Code Online (Sandbox Code Playgroud)
但是当我查看英特尔手册时,我没有看到对应的操作码.该fadd指令以0xDC开始,但它需要一个m64fp操作数,即"内存中的内存四字操作数".
现在,这是否意味着操作数是64位地址(这意味着该fadd指令是64位指令,但不以REX字节作为前缀),或者它只是一个32位地址指向到四字(64位)?
我在这里遗漏了一些微不足道的东西,还是我对编码x86指令的理解错了?
让我们打破这个.
> dc 82 04 08 0d 00 faddl 0xd0804(%edx)
| | \____ ____/
| | V
| | |
| | +---------> 32-bit displacement
| +-----------------> ModRM byte
+--------------------> Opcode
Run Code Online (Sandbox Code Playgroud)
详细查看文档,dc确实是以m64real浮点参数为源.它会将此64位参数添加到ST(0)浮点寄存器.
但是,它是决定64位值来自何处的第二个字节82.这转换为二进制ModRM字节:
+---+---+---+---+---+---+---+---+
| 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
+---+---+---+---+---+---+---+---+
| MOD | REG/OPCD | R/M |
Run Code Online (Sandbox Code Playgroud)
如果您查看链接文档中的表2.2(32位寻址模式的表),您会看到这转换为disp32[EDX].
换句话说,它接下来的32位(四个字节),将其添加到edx寄存器并使用该地址从存储器中提取64位值.