汇编语言子例程
这部分让我彻底困惑。我有一个示例问题,我希望有人可以为我分解为多个步骤,以便我可以吸收它是如何完成的以应用于其他问题。
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
This section has me thoroughly confused. I have an example problem that I am hoping someone can break down into steps for me so that I may absorb how it is done to apply to other problems.
mc: call subr
mr: mov [val],ax
subr: push ax
push bx
push cx
add ax,dx
pop ax
pop bx
pop cx
ret
The book asks what the hex value in the sp and ax register will be for when the code returns from the subroutine and reaches the instruction mr: mov [val],ax
. sp=0100 ax=0002
, but I have no clue as to how to arrive at these answers.
The instruction mc: call subr
saves the address of the next sequential instruction mr: mov [val],ax
on the stack so the subroutine can correctly return. The absolute address in memory where the return address is saved is 1120E
. Can anyone please elaborate on this as well?
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
mc:
处的调用将保存当前地址,因此当subr:
返回时,控制将在mr:
处再次启动。因为
subr:
按该顺序推送 ax、bx 和 cx。然后它按顺序弹出 ax、bx 和 cx,因此从 cx 推送的内容会弹出到 ax 中(反之亦然)。这些的作用是交换 ax 和 cx。add ax, dx
对生成的结果没有实际影响,因为在将 dx 添加到 ax 之后,它立即将 ax 从堆栈中弹出。add
确实会影响标志,但这里没有任何基于标志的操作,因此至少在您显示的代码中,这也没有多大意义。控制权返回到
mr:
后,将ax
中的值写入内存,然后流回subr:
,从而交换ax和cx回到他们开始的地方。IOW,总的来说,这是一种非常缓慢、迂回的方式,可以达到与以下内容大致相同的效果:
就绝对地址而言,没有太多可说的。特别是,如果再次运行相同的代码,它很可能会加载到不同的地址,或者保存在堆栈上的地址可能完全不同。
The call at
mc:
will save the current address, so when thesubr:
returns, control will start again atmr:
.Since
subr:
pushes ax, bx, and cx in that order. It then pops ax, bx, and cx in that order, so what was pushed from cx gets popped into ax (and vice versa). The effect of these is to swap ax and cx. Theadd ax, dx
has no real effect on the result produced, because immediately after adding dx to ax, it pops ax off the stack. Theadd
does affect the flags, but nothing here does anything based on the flags, so at least in the code you've shown, that doesn't mean much either.After control returns to
mr:
, it writes the value inax
to memory, and then flows back intosubr:
, thus swapping ax and cx back to where they started.IOW, the whole this is a very slow, roundabout way of achieving roughly the same effect as:
As far as the absolute address goes, there's not much to say. In particular, chances are pretty good that if you run the same code again, it may be loaded at a different address, o the address saved on the stack may be entirely different.