3

为什么不能从 EBP 寄存器中调用指针地址?我的意思是在下面的代码模式中演示。

  1. 操作码:'0xFF 0x10' -> CALL DWORD PTR DS:[EAX]
  2. 操作码:'0xFF 0x11' -> CALL DWORD PTR DS:[ECX]
  3. 操作码:'0xFF 0x12' -> CALL DWORD PTR DS:[EDX]
  4. 操作码:'0xFF 0x13' -> CALL DWORD PTR DS:[EBX]
  5. 操作码:'0xFF 0x14' -> CALL DWORD PTR SS:[ESP+EDI]
  6. 操作码:'0xFF 0x15 0x012345678' -> CALL DWORD PTR DS:[0x012345678]
  7. 操作码:'0xFF 0x16' -> CALL DWORD PTR DS:[ESI]
  8. 操作码:'0xFF 0x16' -> CALL DWORD PTR DS:[EDI]

“5”在“Intel Instruct manual”中有说明,但从未直接提及“6”,也从未明确指出您不能从 EBP 寄存器中调用它。我知道这不是一个无用的功能,但我想知道为什么英特尔选择这两个寄存器来使用,这只是一个设计选择还是我缺少的东西?(我有一个猜测,但我很好奇真正的原因是什么。)

4

1 回答 1

4

您可以通过 EBP 调用,它只是编码不同。你需要序列

0xff 0x55 0x00

问题是没有偏移量就无法对 EBP 进行编码(上面指定了字节偏移量为 0 的 EBP),因为您通常期望的编码是没有偏移量的 EBP (0x15) 而是意味着 32 位绝对.

另请注意您的0xff 0x14示例——在这种情况下,有一个第三个字节(一个 SIB 字节)对基址寄存器、索引寄存器和比例因子进行编码。ESP+EDI 就像你的例子一样有第三个字节0x3c——你希望第三个字节是0x24ESP

至于为什么他们选择 EBP 和 ESP 作为不能简单编码的寄存器,因为 ESP 是堆栈指针(通常通过 push/pop 指令访问)而 EBP 是帧指针,所以你很少想取消引用它直接没有偏移。至少在设计 80386 时就是这种情况。

于 2011-01-06T03:28:53.763 回答