[英]Stack growing in wrong direction in Linux
我研究过,在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更低的内存地址中,但是这里发生的事情完全相反。 有人可以解释一下这种行为。 这是ideone的链接 。
谢谢。
通常,堆栈从高内存开始增长,堆从低内存增长,因此它们永远不会“碰撞”到彼此。
不过,理论上堆栈在任何一个方向上都可以增长。 x86支持堆栈向任一方向发展,但我从未见过有人故意使用向上增长的堆栈。
最好的部分是英特尔将向下增长的堆栈称为“成长”,而向上增长的堆栈则称为“增长”。
注意: -您不应该假设堆栈框架内局部变量的排序。 编译器可能会将“第一个”变量放在“第一个”的意义上,将其推到当前位置,这意味着“第一个”变量位于更高的地址。 或者它可以在内存中向上组织变量(更有可能)给“第一”变量一个较低的地址。 或者它可以完全随机排列变量。 如果进行优化,它甚至可以消除变量,或者如果它们的生命周期不重叠,则对多个变量使用相同的内存位置。
你可以点击这个链接BUFFER OVERFLOW 7
但知道返回地址不能保证以任何特定方式排列仍然很重要。 如果使用-fomit-frame-pointer
,则基指针不在堆栈中。 正如我之前所说,局部变量的排序符合没有特定的约定。
另一个复杂因素是同一程序中存在多个调用约定。 通常不仅仅通过查看代码地址来告诉函数符合的约定。 堆栈框架可能与您期望的非常不同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.