Jes*_*Joy 31 stack callstack memory-management virtual-memory
我在课本中读到堆栈通过减少内存地址而增长; 也就是说,从较高地址到较低地址.这可能是一个糟糕的问题,但我没有把这个概念弄好.你可以解释吗?
Meh*_*ari 57
首先,它取决于平台.在某些体系结构中,堆栈从地址空间的底部分配并向上增长.
假设像x86这样的架构从地址空间的顶部向下增长,那么这个想法非常简单:
=============== Highest Address (e.g. 0xFFFF)
| |
| STACK |
| |
|-------------| <- Stack Pointer (e.g. 0xEEEE)
| |
. ... .
| |
|-------------| <- Heap Pointer (e.g. 0x2222)
| |
| HEAP |
| |
=============== Lowest Address (e.g. 0x0000)
Run Code Online (Sandbox Code Playgroud)
要增加堆栈,您将减少堆栈指针:
=============== Highest Address (e.g. 0xFFFF)
| |
| STACK |
| |
|.............| <- Old Stack Pointer (e.g. 0xEEEE)
| |
| Newly |
| allocated |
|-------------| <- New Stack Pointer (e.g. 0xAAAA)
. ... .
| |
|-------------| <- Heap Pointer (e.g. 0x2222)
| |
| HEAP |
| |
=============== Lowest Address (e.g. 0x0000)
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,成长组,我们已经降低堆栈指针从0xEEEE在0xAAAA到,而增长堆,你必须增加堆指针.
显然,这是内存布局的简化.实际的可执行文件,数据部分......也加载到内存中.此外,线程有自己的堆栈空间.
你可能会问,为什么堆栈会向下生长.好吧,正如我之前所说的,一些架构反过来,使堆向下增长,堆栈向上增长.将堆栈和堆放在相对的两侧是有意义的,因为它可以防止重叠并允许两个区域自由增长,只要有足够的可用地址空间即可.
另一个有效的问题可能是:程序是否应该减少/增加堆栈指针本身?架构如何将一个架构强加给程序员?为什么它不依赖程序,因为它依赖于架构?虽然你几乎可以打架构并以某种方式摆脱你的筹码在相反的方向,一些指令,特别是call
与ret
该修改堆栈指针直接将要承担另一个方向,弄得一团糟.
zwo*_*wol 23
如今,这很大程度上是因为它已经以这种方式进行了很长时间,很多程序都认为它是这样完成的,而且没有真正的理由去改变它.
当恐龙在地球上漫游而计算机有8kB的记忆时,如果幸运的话,这是一个重要的空间优化.你把堆栈的底部放在内存的最顶端,逐渐减少,然后将程序及其数据放在最底层,malloc
区域越来越大.这样,堆栈大小的唯一限制是程序+堆的大小,反之亦然.如果堆栈开始于4kB(例如)并且长大,那么堆永远不会超过4kB(减去程序的大小),即使程序只需要几百个字节的堆栈.