在某些地方,我已经读过堆栈从较高的地址变为较低的地址,但是当我自己检查它时,我注意到它从较低的地址变为较高的地址。例如,我为地址 2aba5ab06010 的线程分配了堆栈,并且在某些时候发现它的值为 2aba5b7050f0 ,这显然大于堆栈的顶部。
但是当我检查反汇编时,我可以看到函数序言减去%rsp和epilogues添加它,所以在这个意义上,不应该是%rsp的值小于堆栈的顶部。为什么这些矛盾的结果?
请注意,我在x86 64位计算机和gcc编译器上使用Linux。
答案 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分配了堆栈时,你的意思是你从那个地址开始给它一大堆堆栈内存吗?那么你的参考点将高于分配内存的开始,但只有一个参考点你无法确定它的增长方式。