2011-11-01 308 views
0

本节让我彻底困惑。我有一个例子问题,我希望有人可以为我分解步骤,以便我可以吸收它如何应用于其他问题。汇编语言子程序

mc: call subr 
mr: mov [val],ax 
subr: push ax 
     push bx 
     push cx 
     add ax,dx 
     pop ax 
     pop bx 
     pop cx 
     ret 

书要求在SP和AX寄存器中的十六进制值将是什么时,代码从子程序返回并到达指令mr: mov [val],axsp=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对产生的结果没有实际影响,因为在将ax添加到ax之后,它将轴从堆栈中弹出。 add确实会影响标志,但这里没有任何内容会根据标志做任何事情,所以至少在你显示的代码中,这也没有多大意义。

控制返回到mr:后,它将ax中的值写入内存,然后返回到subr:,从而将ax和cx交换回它们开始的位置。

督察,整体而言,这是实现大致相同效果的一个非常缓慢的,迂回的方式:

mc: mov [val], cx 
    ret 

至于绝对地址去,没有太多可说的。特别是,如果你再次运行相同的代码,它可能会被加载到不同的地址,所以保存在堆栈中的地址可能完全不同。

+0

感谢您的快速响应。我认为我现在更了解推动和流行,但是在什么情况下更改了“sp”?我更新了原来的帖子以显示给定的寄存器,所以也许你可以帮助解释我如何用这些值来计算绝对地址。 – raphnguyen

+0

@raphnguyen:绝对地址,你需要PC寄存器,这不包括在你列出的。 'sp'被任何推动或弹出堆栈的东西(包括'call'中的隐式push和'ret'中的隐式pop)所改变。 –

+0

嗯奇怪,我想知道为什么这本书选择了1120E作为五个地址组中的绝对地址。所以,因为有3个“推”呼叫和3个“流行”呼叫,他们互相抵消了吗?我似乎无法找到与“sp”行为对应的部分。它是否随着每个'push'而增加,并且随着每个'pop'而递减? – raphnguyen