assembly - 'call dword ptr [mem32]' 问题的操作码和 ModRM?

标签 assembly opcode

为什么不能从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]

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

最佳答案

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

0xff 0x55 0x00

问题是没有办法对没有偏移量的 EBP 进行编码(上面指定字节偏移量为 0 的 EBP),因为您通常期望的编码是没有偏移量的 EBP (0x15) 而不是 32 -位绝对。

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

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

关于assembly - 'call dword ptr [mem32]' 问题的操作码和 ModRM?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4611341/

相关文章:

arrays - 在程序集中打印数组元素

assembly - 如何根据实模式偏移和寻址确定 x86 机器操作码值?

assembly - 汇编指令数据库?

assembly - 如何阅读汇编操作码引用?

assembly - 什么是数据类型以及它是如何实现的?

assembly - 如何使用 x86 汇编语言将两个 64 位数字相乘?

assembly - 所有程序都可以转换为汇编吗?

assembly - 是否有可能通过软件永久损坏硬件?

assembly - x86在x86-x64中不同或已完全删除的32位操作码

assembly -/4在FF/4中是什么意思?