首页 > 解决方案 > 使用前关于堆栈的假设

问题描述

在使用堆栈之前是否需要“清除”堆栈?换句话说,在使用堆栈之前,是否可以安全地假设它完全为零,或者它是垃圾并且它可以是任何东西?例如,假设我将一个三字节值移动AA AA AA%rbp-4

 ---------------------- %rsp / %rbp

 ---------------------- -1
            AA
 ---------------------- -2
            AA
 ---------------------- -3
            AA
 ---------------------- -4

如果我将四个字节移动到一个寄存器中,例如:

movl -4(%rbp), %eax

我是否首先需要清除堆栈上未使用的字节,还是我们确定堆栈已被清除?

标签: assemblyx86stackcallstack

解决方案


...在使用堆栈之前,假设它完全归零是否安全...

在几乎所有用例中,堆栈在您使用之前就已经“使用”过了。

示例 C 代码:

void someFunction(void)
{
    someOtherFunction();
    functionIHaveWritten();
}

假设堆栈指针的初始值为rsp=0x10F000.

现在该函数someOtherFunction()将使用堆栈,将堆栈指针更改为另一个值(比如说rsp=0x10EF00)并将一些数据(通常是局部变量)存储到 和 之间的内存0x10EF00区域0x10F000

当函数someOtherFunction()返回时,它会将栈指针恢复为rsp=0x10F000,但不会清除栈上被函数覆盖的字节。

清除没有任何意义——这会花费时间,而且大多数函数不需要清除堆栈。

所以当你写的函数functionIHaveWritten()——被调用的时候,栈里面就包含了这个函数写的“垃圾” someOtherFunction()

在使用堆栈之前是否需要“清除”堆栈?

如果要确保堆栈上的所有字节都初始化为零:是。

但是,在大多数情况下,您不需要这样做。


推荐阅读