【问题标题】:Understanding WORD PTR [closed]了解 WORD PTR [关闭]
【发布时间】:2018-07-04 21:02:21
【问题描述】:

我想了解一些 16 位源代码。

我有。

unsigned short addr, d;

addr = &d;

8D46FA // LEA AX,WORD PTR [d]
8946FC // MOV WORD PTR [addr],AX

addr 变为 0x159A

为什么 addr = 0x159A 而不是 0xFA46 ?

此问题已被搁置,但已给出答案并且我已接受。我不是在问寄存器是如何工作的,(似乎人们认为我是,我的问题简单明了,为什么它编译上面的 ASM 而不是我所期望的。)

【问题讨论】:

  • WORD PTR [d] 是说[d] 的冗长方式,因为数据的大小在获取其地址时并不重要。与说LEA AX, [d] 相同,它将d 的地址移动到AX。在 MOV WORD PTR [addr],AX 中,已知 AX 的大小为 16 位,而 WORD PTR [addr] 是一种冗长的说法 [addr] 所以与 MOV [addr], AX 相同。调试器为信息提供的大小可能更多(short 的大小是 16 位 WORD)。
  • 生成的代码似乎正确地将 d 的地址移动到 addr 。我假设这里的变量在一个函数中,因此在堆栈中。 addr 不在内存中的固定点。
  • 调试器以简洁的形式显示了daddr 的地址,但地址实际上最终是lea ax,[bp-0x6]mov [bp-0x4],ax,这对于基于堆栈的变量来说是正常的。任何以 bp 为基数的东西都被自动假定在堆栈段中,因此也与 lea ax,ss:[bp-0x6]mov ss:[bp-0x4],ax 相同。 0xFA = -6 和 0xFC = -4。如果addr 变为 0x159a 则意味着d 的地址是ss:[0x159a]
  • 如果您将变量 d 移动到全局范围(函数外部),您可能会看到一些不同的内容(并且与您的预期不同)。

标签: assembly visual-c++ x86 masm x86-16


【解决方案1】:

反汇编有点混乱。这些地址实际上是相对于BP,这对于局部变量来说是正常的。 lea 在 16 位寻址 means BP+sbyte 中有一个 mod R/M 字节和一个 mod R/M 字节 46

lea的重点是它使用内存操作数编码,所以它肯定需要mod R/M。

【讨论】:

  • 我认为 RegModR/M 字节可能已进入其中。我正在手写一些编译代码,所以我必须详细了解这一点。 (不超过 10 行左右。)
  • 谢谢你,我会回到86规范再读一点。
  • 0x15A0 (地址) - 0x159A (BP) = 0xFA (-0x06); 89(89转/m8,r8); 46 (01 disp8) 000 (AL) 110 ([BP]+disp8) FA (-0x06) = 8946FA。
猜你喜欢
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 2020-05-13
  • 2021-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多