汇编语言子例程

发布于 2024-12-12 20:45:35 字数 679 浏览 2 评论 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

书中询问当代码从子例程返回并到达指令 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我一直都在从未离去 2024-12-19 20:45:36

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,总的来说,这是一种非常缓慢、迂回的方式,可以达到与以下内容大致相同的效果:

mc: mov [val], cx
    ret

就绝对地址而言,没有太多可说的。特别是,如果再次运行相同的代码,它很可能会加载到不同的地址,或者保存在堆栈上的地址可能完全不同。

The call at mc: will save the current address, so when the subr: returns, control will start again at mr:.

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. The add ax, dx has no real effect on the result produced, because immediately after adding dx to ax, it pops ax off the stack. The add 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 in ax to memory, and then flows back into subr:, 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:

mc: mov [val], cx
    ret

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文