如何在 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 中的值是多少
MOV AX, [DI]
MOV AX, [5000h]
MOV AX, [BP+2000h]
LEA AX, [BP+1000h]
[我的答案留在这里供参考,但我撤回了。根据您提供的信息,我了解到您的 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。
我想了解以下问题中 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]
[我的答案留在这里供参考,但我撤回了。根据您提供的信息,我了解到您的 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。