堆栈是向上还是向下增长
在某些地方,我读到堆栈从较高的地址增长到较低的地址,但是当我自己检查时,我注意到它是从较低的地址增长到较高的地址。例如,我为地址 2aba5ab06010 的线程分配了堆栈,并在某个时刻发现其值为 2aba5b7050f0,这明显大于堆栈顶部。
但是当我检查反汇编时,我可以看到函数序言减去 %rsp 而尾声添加它,所以从这个意义上说,%rsp 的值不应该小于堆栈顶部。为什么会出现这些矛盾的结果?
请注意,我在 x86 64 位机器上使用 Linux 和 gcc 编译器。
At some places, I have read that stacks grow from a higher address to a lower address, but when I checked it out myself, I noticed that it grows from a lower to a higher address. For example, I allocated stack for a thread at address 2aba5ab06010 and at some point found out its value to be 2aba5b7050f0, which is clearly greater than the top of the stack.
But when I check the disassembly, I can see that function prologues subtract %rsp and epilogues add it, so in that sense, shouldn't be the value of %rsp less than the top of the stack. Why these contradictory results?
Note that I am using Linux on an x86 64 bit machine and the gcc compiler.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
线程堆栈可以向上或向下增长,具体取决于平台。检查这一点的典型方法是让 A 调用 B 函数,然后
比较 localStackVariableB 和 FromFunctionA 的地址并确定方向。确保优化完全关闭。
The thread stack can grow upwards or downwards depending on the platform. A typically way to check this is let A call B function and with
now compare the address of localStackVariableB and FromFunctionA and determine the direction. Make sure the optimization is turned off completely.
在旧的 DOS 时代,代码和数据段通常加载在内存段的开头,堆位于内存段之上。然后栈位于内存段的顶部并向下向堆增长,而堆则逆着栈增长。现代系统很少有这种方式。
In the old DOS days, it used to be that the code and data segments were loaded at the start of the memory segment, and the heap was above that. Then the stack was at the top of the memory segment and grew down towards the heap, while the heap grew up against the stack. Modern systems seldom has it this way.
放弃公共前缀 (
2ABA
),您似乎声称0x5A...> 0x5B...
。事实并非如此,所以堆栈向下增长。
Discard the common prefix (
2ABA
), and you seem to be claiming0x5A... > 0x5B...
.It isn't, so the stack grew downwards.
通常,当您将堆栈地址传递给线程创建函数时,您会传递已分配内存块的开始 - 这是最低地址,并且在像 x86-64 这样的系统上当堆栈向下增长时,这是堆栈的底部。但是,新线程将从顶部(最高地址)开始使用堆栈。
根据您的数字,我们可以得出结论,您分配的堆栈从
0x2aba5ab06010
开始,并且至少有 12MB 大 - 比如说,在0x2aba5b706010
结束。如果是这样,则意味着您进行测量时正在使用 3872 字节。It is usual, when you pass a stack address to a thread creation function, for you to pass the start of the allocated block of memory - this is the lowest address, and on a system like x86-64 where the stack grows downwards, this is the bottom of the stack. However, the new thread will then start using the stack from the top - the highest address.
From your numbers, we can conclude that your allocated stack started at
0x2aba5ab06010
and was at least 12MB big - say, finishing at0x2aba5b706010
. If so, this would mean that 3872 bytes were in use when you took your measurements.当你说你在 2aba5ab06010 分配了堆栈时,你的意思是你给了它从该地址开始的一块堆栈内存吗?那么你的参考点将位于分配内存的开始之上,但只有一个参考点你无法真正判断它的增长方式。
When you say you allocated the stack at 2aba5ab06010, do you mean that you gave it a chunk of stack memory starting at that address? Then your reference point would be above the start of allocated memory, but with only one reference point you can't really tell which way it is growing.