这部分让我彻底迷茫。我有一个示例问题,我希望有人可以为我分解步骤,以便我可以吸收如何应用于其他问题。
mc: call subr
mr: mov [val],ax
subr: push ax
push bx
push cx
add ax,dx
pop ax
pop bx
pop cx
ret
本书询问当代码从子例程返回并到达指令mr: mov [val],ax
时,sp和ax寄存器中的十六进制值将是什么。 sp=0100 ax=0002
,但我不知道如何得出这些答案。
指令mc: call subr
将下一个顺序指令mr: mov [val],ax
的地址保存在堆栈中,以便子程序可以正确返回。保存返回地址的内存中的绝对地址为1120E
。任何人都可以详细说明这个吗?
registers given:
ax = 0000 bx = 0001 cx = 0002 dx = 0004
si = 0000 di = FFFF bp = 0080 sp = 0100
cs = 1000 ds = 1100 es = 1110 ss = 1111
答案 0 :(得分:1)
mc:
处的来电将保存当前地址,因此当subr:
返回时,控制权将再次从mr:
开始。
由于subr:
按顺序推送ax,bx和cx。然后它按顺序弹出ax,bx和cx,因此从cx推送的内容会弹出到ax(反之亦然)。这些效果是交换ax和cx。 add ax, dx
对产生的结果没有实际影响,因为在将dx添加到ax之后立即将其从堆栈中弹出。 add
确实会影响标志,但这里没有任何内容可以根据标志做任何事情,所以至少在您显示的代码中,这并不意味着什么。
控制返回mr:
后,它将ax
中的值写入内存,然后流回subr:
,从而将ax和cx交换回它们开始的位置。
IOW,整体来说这是一种非常缓慢,迂回的方式,可以达到与以下几乎相同的效果:
mc: mov [val], cx
ret
就绝对地址而言,没有太多可说的。特别值得一提的是,如果再次运行相同的代码,它可能会被加载到不同的地址,o堆栈中保存的地址可能完全不同。