为x86汇编绘制堆栈帧

12

我对如何为我的汇编代码绘制堆栈帧感到困惑。

这是我目前的进展情况,但是你可以看到我在第5步时很困惑,因为我认为我的初始布局是错误的。

图片描述 图片描述

请问您能告诉我哪里错了吗?

4个回答

28

我认为最好从一个图表开始,它显示了堆栈“顶部”处的某些(半)任意空间,并且可能在左侧显示 EBP 和 ESP,用箭头指示它们所指向的位置。我使用实箭头表示“指向”,虚线箭头表示数据移动(回想起来,最好将其反转)。

替代文本


哇,那个图表看起来很酷。你用什么程序画的?我明天再看——因为今晚我的大脑已经炸了。 - Andriy Drozdyuk
我假设图表是从左到右,从上到下的方向。然后我不确定在第三个图表中,你是如何让EBP和ESP最初指向相同的地址的。我的意思是,在之前的图表中,它们是不同的。 - Andriy Drozdyuk
是的 - 那就是 mov %esp, %ebp。当你将 ESP 中的值移动到 EBP 中时,它们最终指向同一个位置... - Jerry Coffin
@Jerry:你介意我在即将到来的会议演讲中使用这张图吗?当然,我会注明出处是你。 - Crashworks
@JerryCoffin,我对第二个图表有一点疑问。当调用push %ebp时,首先ESP会减少4,然后将esp的内容放置在由esp指向的位置,从而在旧EBP和Y(参数)之间创建间隙。 - Amit Singh Tomar

2

在这种情况下,当前ebp(一旦从esp中捕获)与y之间的距离确实为8个字节,因为堆栈上有返回eip和先前ebp的值。就我所知,您的图表是正确的,尽管左侧地址更加混乱 :)


1

该图显示了返回地址下方的参数,实际上是错误的。

假设堆栈向较低地址增长,如果需要将参数放在堆栈上,则它们位于比返回地址更高的地址处。


0
你的图表是正确的。编译器使用了一些优化技巧:第一次调用是“相当正常”的,实际上,“f”参数被放置在堆栈的顶部。第二次调用被推迟到本地上下文清理之后(指令“leave”),并且“h”函数的参数被“回收”以包含“2”。然后对“f”的第二个“调用”变成了一个简单的“jmp”,因为它是调用函数“h”的最后一行(“h”的上下文已经被“leave”抛弃)。
再见!

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