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

时间:2019-01-28 17:10:42

标签: assembly x86 x86-16 real-mode

我试图理解以下问题中 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值是什么

  • MOV AX, [DI]
  • MOV AX, [5000h]
  • MOV AX, [BP+2000h]
  • LEA AX, [BP+1000h]

2 个答案:

答案 0 :(得分:6)

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

Physical Address = segment * 16 + offset
     

Physical Address = segment << 4 + offset

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

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

LEA指令实际上并不访问物理内存,它只是计算内存操作数的有效地址并将该地址加载到寄存器中。使用LEA时,该细分不会出现。一条带有存储器操作数的MOV指令会将存储器操作数的内容移入/移出寄存器。


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

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

  • MOV AX, [5000h]MOV AX, [DS:5000h]相同,因为隐含的段是 DS 。在问题 DS = 1000h中。偏移量为5000h。使用公式segment << 4 +偏移量,我们获得物理地址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 +偏移量,我们获得物理地址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。

答案 1 :(得分:2)

[我的回答留在这里供参考,但我撤回了。从您提供的信息中,我收集到您的x86处理器正在与引导加载期间一样以特权8086兼容模式运行。不幸的是,我没有编写引导加载程序的经验。]

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

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

因此,在执行此代码后,寄存器AX将保存值5000h。

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