8086汇编问题,这段代码是做什么的?

3
我在我的汇编课程中收到了这个问题:
这个过程是做什么的,应该如何调用?
push ebp
mov ebp, esp    
push esi

mov esi, [ebp+4]
mov eax, [esi]
sub eax, [esi+4]
add esi, 8
mov [ebp+4], esi

pop esi
pop ebp
ret

看起来 [ebp+4] 是一个参数而不是返回地址,所以应该使用 "jmp" 而不是 "call" 进行调用。 我真的不明白在 [esi+4]esi+8 (返回地址) 上应该找到什么。 嗯,我真的很困惑,希望你能帮助我。
提前感谢您。


1
带32位寄存器的8086? - Jens Björnhager
3个回答

2
正如您所指出的那样,如果使用call调用此例程,则[ebp+4]是返回地址。但这并不意味着这是一个坏主意。
假设该例程使用call调用。此时,推送到堆栈上的“返回地址”是紧随call操作码后面的字节的地址。让我们把这个地址称为x。然后,该例程从地址x提取两个32位字,一个在地址x处,另一个在地址x+4处。它将第二个字从第一个字中减去,将结果存储在eax中。最后,该例程将值x+8存回堆栈槽[ebp+4],净效果是当到达ret时,执行将在地址x+8处恢复。根据这个假设,该例程看起来像是一种减去位于代码中间的整数的方法,就像这样:
call yourroutine
dd   56478634
dd   18943675
mov  ebx, eax  ; an example instruction

这里,call 指令返回到 mov 指令,并且此时 eax 包含值 37534959(也就是从 56478634 减去 18943675 的结果)。

作为一个代码例程,它并不是非常有用,因为这是一种将 eax 加载为硬编码常量值的复杂方式(代码空间通常在执行过程中为只读)。人们可能会想象,在某些架构上,这样的例程可能出现在动态链接的运行时支持中(动态链接是一个棘手的问题)。

现在,我们假设该例程是通过 jmp 调用的。此时,[ebp+4] 指定了栈顶部的任何内容。该例程获取该值(称其为 y),获取地址 yy+4 处的两个字,将减法结果存入 eax 中,然后将 y+8 存储回 [ebp+4] 位置。最后,ret 将该位置解释为返回地址,即应该跳转执行的某些代码的地址。并不重要的是,该地址没有涉及到 call 操作码的生成;ret 仍然会跳转到该地址。这次,调用代码可能如下所示:

    push   foobar
    jmp    yourroutine
    ...  ; unreached code

foobar:
    dd 56478634
    dd 18943675
    mov  ebx, eax  ; an example instruction

这似乎是一个带有一些内在的eax加载的参数化跳转。这样的代码可以存在于某些线程代码解释器的实现中。然而,作为一道作业问题,我相信这不是作者想要表达的意思(线程代码解释器甚至比动态链接还要复杂)。

1

当您调用此函数时,返回地址(调用后的指令地址)将被推送到堆栈上,在第一个函数序言之后,[ebp+4] 引用该返回地址。然后,函数体将此地址视为 2 个整数,这些整数被减去,结果放在 eax 中,然后返回地址增加 8,即这 2 个整数的大小为 add esi,8mov [ebp+4], esiret 只是将我们带回到新的返回地址(希望这是有效的指令...)。

一个奇怪的函数,在某些自修改代码等中看起来很合适...


但是p+=2没有任何效果,因为p是一个堆栈变量。 - Prof. Falken
您提前得到了我的投票,所以我不能再点赞了。(我对您很有信心呢...) :-) - Prof. Falken
1
事情变得更加清晰了,但有一件事我不明白。当我们使用“ret”时,eip <- esp。因此,当过程结束时,返回地址应该在[ebp+4]上找到,那么它返回到哪里呢? - Dmorrigan
当您进行调用时,当前的eip会被推送到堆栈上,实际上[ebp+4]就是返回地址。 - Henno Brandsma
我猜想编写这个代码的人没有测试过它,并且假设没有帧指针,或者没有很好地计算第一个参数的偏移量。 - ninjalj

1

不,它肯定应该使用call调用 - 它在结尾处有一个ret

就它的功能而言,你应该坐下来拿一张纸和寄存器列表,逐步地在脑海中执行这段代码,并随着执行更新寄存器。然后很明显就能知道发生了什么:

eax:
esp:
ebp:
esi:

以及其他相关的内存(例如堆栈顶部周围的区域)。

这是学习编程的理想方式(至少对于小程序而言),因为您可以学会详细分析事物并真正地理解它们。我恐怕这就是我为作业提供的全部帮助了 :-)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接