在函数调用中从 %esp 中减去分配了多少空间?

Posted

技术标签:

【中文标题】在函数调用中从 %esp 中减去分配了多少空间?【英文标题】:How much space is allocated by subtracting from %esp in a function call? 【发布时间】:2013-02-13 05:20:18 【问题描述】:

C++、ATT 汇编

我有以下汇编代码:

push %ebp
mov  %esp, %ebp
sub $0x28, %esp
(...)

我的教科书声称,通过从 %esp 中减去 0x28(作为堆栈形成的一部分),为变量分配了 12 个字节。为什么栈减十进制 40 会分配 12 个字节?

【问题讨论】:

【参考方案1】:

这会在堆栈上分配 40 个字节。但是,除了局部变量之外,它还有其他用途,所以我猜其余部分用于对齐和未来函数调用的参数。

由于函数参数也在堆栈上传递,因此该函数想要传递给另一个函数的任何参数都需要有空间。在执行调用时可以使用push 分配此空间,但在函数开头分配一次空间并稍后使用mov 将数据放置到位是很常见的。如果您的函数为局部变量使用 12 个字节,则最多可留出 28 个字节供以后使用的函数参数。

还可以为对齐分配一些额外的空间。除了 Jerry 提到的变量对齐之外,许多系统都希望堆栈指针与某个值对齐,因此如果您要进行函数调用,则需要保留这一点。在 32 位系统上,这通常是 8 个字节,但在这种情况下也可能是 16 个。

【讨论】:

@Jerry 这就是我的意思。书中的函数要调用另一个函数,所以需要空间。我的编辑是否使它更清晰? 这种解释是有道理的——我对所有的空间和只有几个变量感到困惑。该空间用于参数。谢谢【参考方案2】:

我怀疑你可能误读了你的书,但如果你没有读错,我觉得这本书在这方面有误。

从堆栈指针中减去 40 分配 40 个字节。这可能并不总是完全正确1,但与它的任何偏差通常都非常小。


    例如,如果您在 32 位代码中分配一个 8 字节对象,它可以分配一些额外的空间(总共 12 个字节),因此它可以确保 8 字节对象具有 8 字节对齐。同样,在 32 位代码中,您通常只能以(至少)32 位增量调整堆栈指针,因此具有一个 char 局部变量的函数通常仍会从堆栈指针中减去至少 4 以腾出空间为它。

【讨论】:

此外,如果您使用的是 GCC,默认情况下 GCC 也会尝试将堆栈对齐到 16 字节边界(另请参阅:-mpreferred-stack-boundary。 我正在使用 GCC。这是有道理的——我关心的变量是从 %ebp 偏移的。分配的其余部分必须用于将来的参数。谢谢

以上是关于在函数调用中从 %esp 中减去分配了多少空间?的主要内容,如果未能解决你的问题,请参考以下文章

在OD 反汇编关于EBP 和ESP 局部变量 和函数参数 区别 比如:

分配的堆栈空间没用?

c语言中数组名作为函数参数

Protostar——stack0

静态变量

为啥在分配没有后续函数调用的大数组时,GCC 会向堆栈指针减去错误的值?