堆栈是向上还是向下增长

Posted

技术标签:

【中文标题】堆栈是向上还是向下增长【英文标题】:Does stack grow upwards or downwards 【发布时间】:2011-12-28 16:55:25 【问题描述】:

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

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

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

【问题讨论】:

视情况而定,为什么这对任何人都重要? 如果您将您的地址 (2aba5b7050f0) 转换为十进制值:46979886371056 -- 对另一个地址执行相同操作: (2aba5ab06010)->46979873792016 => 46979886371056 - 4697987792016 = 2您分配的地址大于稍后的地址。这意味着,堆栈从较高的值变为较低的值。 提供有关您的支票的更多详细信息。目前尚不清楚您到底检查了什么。此外,2aba5ab06010 小于 2aba5b7050f0,而不是更大。你为什么断定它是向上增长的? 对不起,Andrey 和 w00,我把值倒序排列了,现在我已经更正了。 【参考方案1】:

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

void FunctionB( int* FromFunctionA )

   int localStackVariableB;
   //Compare &localStackVariableB and FromFunctionA addresses



 void FunctionA( )

   int localStackVariableA;
   FunctionB( &localStackVariableA) 

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

【讨论】:

同意平台。但是 x86 Linux 会下降——如果 3.x 内核没有改变的话。【参考方案2】:

在过去的 DOS 时代,代码和数据段通常在内存段的开头加载,而堆在此之上。然后堆栈位于内存段的顶部并朝堆向下增长,而堆则靠着堆栈增长。现代系统很少有这种方式。

【讨论】:

【参考方案3】:

丢弃通用前缀 (2ABA),您似乎在声明 0x5A... > 0x5B...。 不是,所以堆栈向下增长。

【讨论】:

不小心把它倒序了,现在我已经更正了。【参考方案4】:

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

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

【讨论】:

【参考方案5】:

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

【讨论】:

以上是关于堆栈是向上还是向下增长的主要内容,如果未能解决你的问题,请参考以下文章

我的堆栈是向上增长而不是向下增长吗? [复制]

栈的生长方向理解

为啥堆栈不向上增长(为了安全)?

如何检测在radlistview中是向上滚动还是向下滚动

js如何判断鼠标滚轮是向下还是向上滚动

有啥方法可以知道用户是向上还是向下滚动表格视图?在swift IOS中[重复]