如何在 MOV 和 LEA 指令后确定 AX 中的结果

How can I determine the result in AX after MOV and LEA instructions

我想了解以下问题中 AX 寄存器的内容,我不明白我怎么知道 [5000h] 或 [DI]在示例中。

寄存器和内存的状态定义为:

CS=3000 [53000]=BBBB [33000]=6666 [13000]=1111
DS=1000 [54000]=CCCC [34000]=7777 [14000]=2222
SS=5000 [55000]=DDDD [35000]=8888 [15000]=3333
DI=7000 [56000]=EEEE [36000]=9999 [16000]=4444
BP=4000 [57000]=FFFF [37000]=AAAA [17000]=5555

这些指令在 AX 中的值是多少

[我的答案留在这里供参考,但我撤回了。根据您提供的信息,我了解到您的 x86 处理器在启动加载期间以特权 8086 兼容模式运行。不幸的是,我没有编写引导加载程序的经验。]

寄存器中的旧数据在新数据到达时被覆盖。因此,只有 LEA 指令会影响此结果。

此外,LEA 指令很特殊:它不会解引用它计算的地址。在您的示例中,由于 BP 包含 4000h,因此 LEA 计算的地址为 4000h + 1000h == 5000h。最后一个地址 未使用, 但仅存储在 AX 寄存器中以备将来使用。

因此,在这段代码执行结束时,寄存器 AX 将保存值 5000h。

澄清一下,我并没有说寄存器 AX 将保存存储在内存中地址 5000h 的数据的副本。相反,我说的更简单:寄存器 AX 将保存值 5000h。

这是一道学术题,但涉及实模式的一些概念20-bit segment:offset addressing。实模式下的所有内存地址总是由两部分组成——一个段和一个偏移量。这两部分结合在一起生成物理地址,公式为:

Physical Address = segment * 16 + offset

or

Physical Address = segment << 4 + offset

两者都产生相同的结果,因为向左移动 4 位与乘以 16 十进制(或 10h 十六进制)相同。

您会发现,指令可能会显式指定一个段,而当未指定时,总会有一个隐式段。一般规则是,如果内存地址使用BP那么内存操作数是相对于SS段的,否则是相对于DS段。

LEA指令实际上并不访问物理内存,它只是计算内存操作数的有效地址并将地址加载到寄存器中。使用 LEA 段不会起作用。带有内存操作数的 MOV 指令会将内存操作数的内容 to/from 移动到寄存器。


您问题中给出的所有值均以十六进制形式给出。回答您的问题:

  • MOV AX, [DI]MOV AX, [DS:DI] 相同,因为隐含的段是 DS。题中DS=1000h。 DI=7000h。偏移量为 DI。使用公式 segment<<4 + offset 我们得到物理地址 1000h<<4+7000h = 10000h+7000h=17000h。问题指出内存地址 [17000]=5555 所以移动到 AX 的值是 5555h.

  • MOV AX, [5000h]MOV AX, [DS:5000h] 相同,因为隐含的段是 DS。题中DS=1000h。偏移量是 5000h 。使用公式 segment<<4 + offset 我们得到物理地址 1000h<<4+5000h = 10000h+5000h=15000h。问题指出内存地址 [15000]=3333 所以移动到 AX 的值是 3333h.

  • MOV AX, [BP+2000h]MOV AX, [SS:BP+2000h] 相同,因为隐含的段是 SS。题中SS=5000h和BP=4000h。偏移量是 BP+2000h 。使用公式 segment<<4 + offset 我们得到物理地址 5000h<<4+(4000h+2000h) = 50000h+(4000h+2000h)=56000h。问题指出内存地址 [56000]=EEEE 所以移动到 AX 的值是 EEEEh。

  • LEA AX, [BP+1000h] :该段没有发挥作用,因为它是一条 LEA 指令。题中BP=4000h。偏移量为BP+1000h=4000h+1000h = 5000h。由于 LEA 仅计算地址并将其存储在寄存器中,因此 AX 中的值将为 5000h。