堆栈是向上还是向下增长
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 分配堆栈时,你的意思是你给了它一块从那个地址开始的堆栈内存吗?那么您的参考点将高于分配内存的起点,但只有一个参考点您无法真正判断它的增长方式。
【讨论】:
以上是关于堆栈是向上还是向下增长的主要内容,如果未能解决你的问题,请参考以下文章