为什么不能从EBP寄存器中调用指针地址呢?以下代码模式演示了我的意思。
- 操作码:'0xFF 0x10' -> CALL DWORD PTR DS:[EAX]
- 操作码:'0xFF 0x11' -> CALL DWORD PTR DS:[ECX]
- 操作码:'0xFF 0x12' -> CALL DWORD PTR DS:[EDX]
- 操作码:'0xFF 0x13' -> CALL DWORD PTR DS:[EBX]
- 操作码:'0xFF 0x14' -> CALL DWORD PTR SS:[ESP+EDI]
- 操作码:'0xFF 0x15 0x012345678' -> CALL DWORD PTR DS:[0x012345678]
- 操作码:'0xFF 0x16' -> CALL DWORD PTR DS:[ESI]
- 操作码:'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/