“栈”顶到底是上面还是下面?高地址还是低地址?
我在看《流程是什么样跑起来的》这两本书时,看见下面梵高图忽然很多困惑
那个是栈的重新分配,特别针对栈我提过三个推论,
(1)栈从高门牌号向低门牌号快速增长。
(2)栈是Kosaraju快速增长。
不过里头为何是自自顶向下快速增长?除了就呢说从高门牌号往门牌号快速增长,我提过下面是高门牌号,那个是不是就从低门牌号往高门牌号快速增长了?何况是手写错了?忽然就懵了。。。
后翻查了好一会才捋确切。
具体来说要明晰三个基本概念:栈的前述花纹是三个玻璃杯。玻璃杯的顶部总有一天称栈底,玻璃杯的顶端总有一天称args。
而那个玻璃杯在前述的缓存储存情形是利穆县的,如下表所示:
栈和堆这三个玻璃杯相较,三个利穆县,三个正放。因此对栈而言下面是栈底下面是args,而对堆而言,下面是堆顶下面是堆底。
这儿再稍稍扩充下,栈和堆约莫除了下列差别:
(1)栈是系统自动重新分配和释放,而堆需要流程员手动重新分配释放。因此总体上栈的重新分配效率要比堆高。
(2)栈中存放的内容包括函数返回门牌号、相关参数、局部变量(那个用最多)和寄存器内容等。当主函数调用另外三个函数的时候,要对当前函数执行断点进行保存。而堆中具体存放内容是由流程员来填充的。
(3)每个进程拥有的栈的大小要远远小于堆的大小。
然后接着说,
在很多里头,他们喜欢把堆那个玻璃杯倒过来,这样下面就是栈底,下面就变成args。同样下面就变成了高门牌号而下面就变成了低门牌号,而总有一天要记住,不论什么样变,栈的快速增长方向总有一天从杯底到杯顶。
后再看下面的推论,会发现不论里头却是网上都没有错。只不过很多人介绍栈的时候喜欢给栈换个方向罢了。另外,对栈是Kosaraju快速增长,这儿的顶和下说的就是方向,就从上往下快速增长,从前述缓存空间栈分布情形说的。如果把栈倒过来,这种说法就会看起来不太准确了。而栈底和args总有一天是杯底和杯顶,那个底和顶就和方向没关系了。
对x86的cpu主要有下图的这些寄存器:
其中和栈有关的主要是ebp和esp三个寄存器。ebp总是指向栈底,b表示base嘛,esp总是指向args。
一开始会让esp的值等于ebp的值,随着函数的局部变量往栈中保存,cpu会自动让esp会逐渐往低门牌号方向移动来重新分配栈空间,而当需要进行栈清理时,只需要再次将esp的值等于ebp,就能从逻辑上将栈中的数据清除。(一般局部变量会优先往寄存器中保存,寄存器不够用时才会开始考虑栈)
在数据结构中的栈和缓存中的栈讲的不是三个东西,不过数据结构中的栈同样类似于三个玻璃杯,特点就是先进后出,因为先进去的数据被压到杯底不好取出来嘛。而数据结构的堆则和缓存中的堆就完全不同了,数据结构中的堆是个树形结构。这块不能混淆。
栈大致就是这么个情形。