我已经研究过,在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。
谢谢。
答案 0 :(得分:-3)
通常,堆栈从高内存开始增长,堆从低内存中增长,因此它们永远不会突然进入&#34;彼此。
但理论上,堆栈可以在任一方向上增长。 x86支持堆栈向任意方向发展,但我从未见过任何人故意使用向上增长的堆栈。
最好的部分是,英特尔将向下增长的堆栈称为&#34;成长&#34;和向上增长的堆栈随着#34;成长。&#34;
注意: - 您不应该假设堆栈框架内局部变量的排序。编译器可能会先放置&#34;&#34;变量&#34;第一&#34;在当前位置推动它的意义上,意味着&#34;第一个&#34;变量位于更高的地址。或者它可以在内存中组合变量(更有可能)给出&#34;首先&#34;变量较低的地址。或者它可以完全随机排列变量。如果进行优化,它甚至可以消除变量,或者如果它们的生命周期不重叠,则对多个变量使用相同的内存位置。
您可以点按此链接 BUFFER OVERFLOW 7
但要知道返回地址不能保证以任何特定方式排列仍然很重要。如果使用-fomit-frame-pointer
,则基指针将不在堆栈中。正如我之前所说,局部变量的排序符合没有特定的约定。
另一个复杂因素是同一程序中存在多个调用约定。通常不仅仅通过查看代码地址来告诉函数符合的约定。堆栈框架看起来可能与您期望的完全不同。