gpt4 book ai didi

assembly - 我应该如何使用英特尔的文档获取与 x86 中的 `ModeR/M` 指令相对应的 `call dword ptr` 字节?

转载 作者:行者123 更新时间:2023-12-03 17:53:00 25 4
gpt4 key购买 nike

我在VS2017中调试了以下代码(注意下面的断点):

enter image description here

下面你会发现上面提到的断点的反汇编:

enter image description here

如上图所示,编译器为指令call dword ptr [fp]生成的机器码是 FF 55 F8哪里FF是调用指令的操作码,55ModeR/M 的值字节和 F8是一个值为 -8 的 8 位位移,我将在下面解释。

现在,如果您查看下面的“表 2-2:带有 ModeR/M 的 32 位寻址形式”字节,该字节来自英特尔的“64 位 IA-32 架构软件开发人员手册”的第 2A 卷,您会注意到我突出显示了上面提到的数字55对应一个有效地址[EBP]+disp8 .也就是说,CALL汇编器中的指令将跳转到其地址是从寄存器EBP中的地址加上上面提到的8位位移值-8得到的指令。而且这个地址是正确的。它对应于最终将代码传输到函数 f 的 JMP 指令的地址。 .

enter image description here

因此,一切看起来都很好。但是我遗漏了一个重要的点:我应该获得 ModeR/M byte 使用英特尔手册中的 CALL 指令引用和上面显示的表 2.2。但我仍然不知道如何做到这一点。任何提示都将受到高度赞赏,因为我已经为此工作了几天,但我对此仍然一无所知。

最佳答案

您缺少的是操作码的一部分是在 ModR/M 字节中编码的。通常,ModR/M 字节编码两个操作数。第一个操作数是表左侧行标签中给出的寄存器或内存操作数,而第二个操作数是表顶部列标题给出的寄存器。对于只有一个操作数的指令,如 CALL 指令,第二个操作数用于提供额外的操作码位。

如果您查看 CALL 指令的文档,您会看到“在 r/m32 中给出的绝对间接地址调用”指令的操作码被列为 FF /2 . /2表示 ModR/M 字节中的附加操作码位在该指令中的值为 2。如果您随后查看“(十进制)/数字(操作码)”列标题,您将看到数字 2 出现在列的开头。如果你往下看那一栏,你会看到 55在标有“[EBP] + disp8”的行上。

这在英特尔软件开发人员手册第 2 卷的指令汇总表中的 3.1.1.1 操作码列(不带 VEX 前缀的指令)部分中有记录:

  • /digit — A digit between 0 and 7 indicates that the ModR/M byte of the instruction uses only the r/m (register or memory) operand. The reg field contains the digit that provides an extension to the instruction's opcode.


您唯一缺少的另一件事是 call dword ptr [fp]是反汇编程序生成的文本。它从未组装过,如何组装取决于如何 fp被定义为。反汇编器从编译器生成的调试信息中知道局部变量 fp 在哪里。存在于堆栈中,并且知道 [ebp - 8]可以用来访问它。它显示 fp而不是 [ebp - 8]因为在大多数情况下前者更有意义。您应该可以稍后通过取消选中“显示符号名称”来查看。

请注意 call std::operator<<std:char_traits<char> >无论如何都无法组装生产线 std , operator等被定义,因此表明您正在查看的反汇编实际上并不意味着要组装。反汇编程序经常出现这种情况。输出旨在提供信息,这是比查看十六进制字节序列更好的替代方法。这并不意味着是一个可逆的过程。

关于assembly - 我应该如何使用英特尔的文档获取与 x86 中的 `ModeR/M` 指令相对应的 `call dword ptr` 字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58651136/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com