拆解'faddl'指令

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指令的理解错了?

pax*_*blo 5

让我们打破这个.

> 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位值.