堆栈是向上还是向下增长

时间:2011-11-14 14:20:05

标签: c gcc 64-bit x86 stack

在某些地方,我已经读过堆栈从较高的地址变为较低的地址,但是当我自己检查它时,我注意到它从较低的地址变为较高的地址。例如,我为地址 2aba5ab06010 的线程分配了堆栈,并且在某些时候发现它的值为 2aba5b7050f0 ,这显然大于堆栈的顶部。

但是当我检查反汇编时,我可以看到函数序言减去%rsp和epilogues添加它,所以在这个意义上,不应该是%rsp的值小于堆栈的顶部。为什么这些矛盾的结果?

请注意,我在x86 64位计算机和gcc编译器上使用Linux。

5 个答案:

答案 0 :(得分:6)

线程堆栈可以根据平台向上或向下增长。检查此功能的一种典型方法是让 A 调用 B 函数并使用

void FunctionB( int* FromFunctionA )
{
   int localStackVariableB;
   //Compare &localStackVariableB and FromFunctionA addresses
}


 void FunctionA( )
{
   int localStackVariableA;
   FunctionB( &localStackVariableA) 
}

现在比较 localStackVariableB 和FromFunctionA的地址并确定方向。确保完全关闭优化。

答案 1 :(得分:1)

在旧的DOS时代,过去的代码和数据段是在内存段的开头加载的,而堆在它之上。然后堆栈位于内存段的顶部,并向堆向下扩展,而堆在堆栈中长大。现代系统很少有这种方式。

答案 2 :(得分:1)

弃掉公共前缀(2ABA),您似乎声称0x5A... > 0x5B...。 它不是,所以堆栈向下发展。

答案 3 :(得分:1)

通常,当您将堆栈地址传递给线程创建函数时,为了传递已分配的内存块的 start - 这是最低的地址,并且在类似的系统上堆栈向下增长的x86-64,这是堆栈的 bottom 。但是,新线程将从顶部开始使用堆栈 - 最高地址。

根据您的数字,我们可以得出结论,您分配的堆栈始于0x2aba5ab06010且至少12MB大 - 比如说,在0x2aba5b706010结束。如果是这样,这意味着您在进行测量时会使用3872个字节。

答案 4 :(得分:0)

当你说你在2aba5ab06010分配了堆栈时,你的意思是你从那个地址开始给它一大堆堆栈内存吗?那么你的参考点将高于分配内存的开始,但只有一个参考点你无法确定它的增长方式。