堆栈在Linux中以错误的方向发展

时间:2014-07-28 07:45:14

标签: c linux memory-layout

我已经研究过,在linux系统中,堆栈从高内存地址增长到低内存地址。为了测试这个,我写了一个小代码:

#include<stdio.h>
void func() {
    int var1;
    int var2;
    printf("Func: %p %p",&var1,&var2);
}

int main() {
    int var1;
    int var2;
    printf("Main: %p %p\n",&var1,&var2);
    func();
    return 0;
}

当我在ideone中运行时,我得到以下输出:

Main: 0xbfd958f0 0xbfd958f4
Func: 0xbfd958f8 0xbfd958fc

根据教科书,Func应该存储在比Main更低的内存地址中,但是在这里发生的事情是完全相反的。有人可以解释一下这种行为。这是link to ideone

谢谢。

1 个答案:

答案 0 :(得分:-3)

通常,堆栈从高内存开始增长,堆从低内存中增长,因此它们永远不会突然进入&#34;彼此。

但理论上,堆栈可以在任一方向上增长。 x86支持堆栈向任意方向发展,但我从未见过任何人故意使用向上增长的堆栈。

最好的部分是,英特尔将向下增长的堆栈称为&#34;成长&#34;和向上增长的堆栈随着#34;成长。&#34;

注意: - 您不应该假设堆栈框架内局部变量的排序。编译器可能会先放置&#34;&#34;变量&#34;第一&#34;在当前位置推动它的意义上,意味着&#34;第一个&#34;变量位于更高的地址。或者它可以在内存中组合变量(更有可能)给出&#34;首先&#34;变量较低的地址。或者它可以完全随机排列变量。如果进行优化,它甚至可以消除变量,或者如果它们的生命周期不重叠,则对多个变量使用相同的内存位置。

您可以点按此链接 BUFFER OVERFLOW 7

但要知道返回地址不能保证以任何特定方式排列仍然很重要。如果使用-fomit-frame-pointer,则基指针将不在堆栈中。正如我之前所说,局部变量的排序符合没有特定的约定。

另一个复杂因素是同一程序中存在多个调用约定。通常不仅仅通过查看代码地址来告诉函数符合的约定。堆栈框架看起来可能与您期望的完全不同。