用于“调用 dword ptr [mem32]”的操作码和 ModRM问题?
为什么不能从 EBP 寄存器调用指针地址?我的意思在下面的代码模式中得到了演示。
- 操作码:'0xFF 0x10'->调用 DWORD PTR DS:[EAX]
- 操作码: '0xFF 0x11' ->调用 DWORD PTR DS:[ECX]
- 操作码: '0xFF 0x12' ->调用 DWORD PTR DS:[EDX]
- 操作码: '0xFF 0x13' ->调用 DWORD PTR DS:[EBX]
- 操作码: '0xFF 0x14' ->调用 DWORD PTR SS:[ESP+EDI]
- 操作码: '0xFF 0x15 0x012345678' ->调用 DWORD PTR DS:[0x012345678]
- 操作码: '0xFF 0x16' ->调用 DWORD PTR DS:[ESI]
- 操作码: '0xFF 0x16' -> CALL DWORD PTR DS:[EDI]
“Intel 指令手册”中注明了“5”,但从未直接引用过“6”,也从未明确指出不能从 EBP 寄存器调用它。我知道这不是一个无用的功能,但我想知道为什么英特尔选择使用这两个寄存器,这只是一个设计选择还是我缺少的东西? (我有一个猜测,但我很好奇真正的原因是什么。)
Why can't you call a pointer address from the EBP register? What I mean by this is demonstrated in the follow code pattern.
- OpCode: '0xFF 0x10' -> CALL DWORD PTR DS:[EAX]
- OpCode: '0xFF 0x11' -> CALL DWORD PTR DS:[ECX]
- OpCode: '0xFF 0x12' -> CALL DWORD PTR DS:[EDX]
- OpCode: '0xFF 0x13' -> CALL DWORD PTR DS:[EBX]
- OpCode: '0xFF 0x14' -> CALL DWORD PTR SS:[ESP+EDI]
- OpCode: '0xFF 0x15 0x012345678' -> CALL DWORD PTR DS:[0x012345678]
- OpCode: '0xFF 0x16' -> CALL DWORD PTR DS:[ESI]
- OpCode: '0xFF 0x16' -> CALL DWORD PTR DS:[EDI]
'5' is noted in "Intel Instruct manual" but '6' is never directly referred to and it is never explicitly stated that you cannot call it from the EBP register. I know this isn't a useless feature but I was wondering why Intel choose those two registers to utilize, was it just a design choice or is their something I am missing? (I have a guess but I'm curious what the real reason is.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你可以通过EBP调用,只是编码不同。你需要序列
事情是没有办法对没有偏移量的EBP进行编码(上面指定了字节偏移量为0的EBP),因为你通常期望的是没有偏移量(0x15)的EBP编码意味着32 位绝对。
另请注意您的
0xff 0x14
示例 - 在这种情况下,有一个第三个字节(SIB 字节)对基址寄存器、索引寄存器和比例因子进行编码。像您的示例一样,ESP+EDI 有一个 0x3c 的第 3 个字节 - 您希望第 3 个字节为 0x24 以获得 ESP 至于为什么他们选择EBP和ESP作为不能简单编码的寄存器,因为ESP是堆栈指针(因此通常通过push/pop指令访问)而EBP是帧指针,所以你很少想直接取消引用它而不需要一个偏移量。至少80386设计时是这样的。
You can call via EBP, its just encoded differently. You need the sequence
The thing is that there's no way to encode EBP without an offset (the above specifies EBP with a byte offset of 0), as the encoding that you'd normally expect to be EBP without an offset (0x15) instead means 32-bit absolute.
Also note your
0xff 0x14
example -- in that case there's a 3rd byte (a SIB byte) that encodes a base register, index register, and a scale factor. ESP+EDI like your example has a 3rd byte of0x3c
-- you want the 3rd byte to be0x24
to get just ESPAs to why they chose EBP and ESP as the registers that can't be encoded simply, its because ESP is the stack pointer (so is normally accessed by push/pop instructions) while EBP is the frame pointer, so you rarely want to dereference it directly without an offset. At least that was the case when the 80386 was designed.