从函数返回时,是否清除了函数的堆栈框架,还是将其保留在堆栈上

时间:2019-08-11 16:41:33

标签: assembly visual-c++ callstack

我在互联网上进行了大量研究,它告诉我,当函数返回时,堆栈上的堆栈框架已清除(销毁)。

但是我怀疑情况并非如此。

我正在并排使用汇编语言和C ++代码进行调试,并且从C ++代码看来,堆栈框架似乎没有清除,但是当main()调用另一个函数时,堆栈框架被覆盖了。

>

我并排查看了汇编代码。而且,当我们将值弹出回寄存器时,是将堆栈中的值简单地复制回寄存器中,而对该堆栈不采取进一步的操作。还是将值复制到寄存器中并从堆栈中删除?

C ++代码:

#include<iostream>
using namespace std;

int* MyFunc(int*);

int main() {
    int* a, b;
    b = 10;
    a = MyFunc(&b);
    return 0;
}

int* MyFunc(int* ptrB)
{
    int inta;
    inta = (*ptrB) * (*ptrB);
    return (&inta);
}

现在,当MyFunc返回&inta时,in main将获取inta的地址。但这很危险,因为如果调用另一个函数,则在将inta的地址分配给-之后,在该步骤之后取消引用a(即* a)将是不确定的。因为inta地址处的内容可能会被覆盖。 看来inta的地址已被覆盖。当MyFunc返回main时,不是清除MyFunc的堆栈框架(清理,清空)。 我之所以这样说,是因为* a在调用函数之前仍然可以给出正确的结果。 我以函数返回时未清除(清空,销毁)MyFunc堆栈框架的假设是否正确?只是堆栈指针(ESP)移到main了?

1 个答案:

答案 0 :(得分:2)

所有数据保留在内存中。唯一更改的参数是堆栈顶部指针(esp)和堆栈帧基础(ebp)。堆栈帧是一个有点抽象的概念,它仅由这两个寄存器的值定义。因此,尽管esp上方的区域可能包含先前堆栈帧中剩余的数据,但该区域还是“不可见”