[笨叔点滴3] “栈”谁便宜了()
“ 有一次和女同学A吃饭,她带着小姑凉一块。在吃饭期间,同学给夹了块豆腐,小姑凉用天真无邪的眼神看着我:笨叔,你除了占我妈便宜,你还占过谁的便宜? 我顿时无语了。。。”
上面是网上的一个小段子,生活里经常有人说谁谁占了谁的便宜?那计算机是不是也有占小便宜呢?计算机里还真有不少便宜可以“栈”,只不过不是“占”,而是各种形式的“栈”,不知道大家知不知道计算机里有多少个栈?比如说:
内核栈中断栈进程栈线程栈硬件栈软件栈堆栈还有人占着茅坑昨天我们聊了ARM32上或是奇葩或者先进的中断栈,我们今天继续来聊“栈”。
01 啥是栈
—
先看看啥是栈?栈的英文叫做stack。那中文里栈是怎么解释的呢?
1.储存货物或供旅客住宿的房屋:货栈|客栈。
2.养牲畜的竹、木栅栏:马栈。
那在计算机,它是啥呢,其实就是一个存放数据的数据结构类型。一种只能在一端进行插入和删除操作的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。看下面这个图应该比较清楚了。
文章图片
这种数据结构的特点是 后入先出 (LIFO, Last In First Out),数据只能在串列的一端 (称为:栈顶 top) 进行 推入 (push) 和 弹出 (pop) 操作。向栈中存储数据称为PUSH,从栈中取数据称为POP。
大多数的处理器架构,都有实现硬件栈。有专门的栈指针寄存器,以及特定的硬件指令来完成 入栈/出栈 的操作。例如在 ARM 架构上,R13 (SP) 指针是堆栈指针寄存器,而 PUSH 是用于压栈的汇编指令,POP 则是出栈的汇编指令。
我们常常听人说,堆栈,那堆栈是个什么鬼?究竟是堆呢还是栈呢?其实堆栈本身就是栈,只是换了个抽象的名字,换了个马甲,有些人就昏了。
那堆是什么?在数据结构里,堆可以被看成是一棵树,如:堆排序。在操作系统里,堆是操作系统里管理内存的一种方式, 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。而栈,由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。
所以,堆和栈还有堆栈,他们三个是不是容易搞混了。
02 栈有啥子用嘛?
—
栈主要是有两大作用,一个是函数调用,另外一个是进程调度。
先说说函数调用。我们知道函数调用需要注意哪些东西?大家想到的可能是
参数怎么传
函数返回值怎么传
那在不同的计算机体系结构里,有不同的做法,但是他们相同的地方是一定会用到栈。
ARM和ARM64使用的是ATPCS(ARM-Thumb Procedure Call Standard/ARM-Thumb过程调用标准)的函数调用约定。
对于ARM来说:
参数1~参数4 分别保存到 R0~R3 寄存器中 ,剩下的参数从右往左一次入栈,返回值存放在 R0 中。
对于ARM64来说:
参数1~参数8 分别保存到 X0~X7 寄存器中 ,剩下的参数从右往左一次入栈,返回值存放在 X0 中。
总之,会用到栈来保存函数调用的参数。另外还有一个东西需要保存,那就是局部变量。
以ARM32为例,一个函数A调用另外一个函数B的栈的布局图如下。fp寄存器(r11)和sp寄存器两个指向的区域,称为一个栈帧(stack frame),函数调用经常是嵌套的,在同一时刻,栈中会有多个函数的信息。每个未完成运行的函数占用一个独立的连续区域,即栈帧。栈帧存放着函数参数,局部变量及恢复前一栈帧所需要的数据等。
文章图片
如上图所示,假设当前运行在函数B里面,那么当前的fp和sp寄存器所指示的区域就是当前的栈,栈帧B。当函数B返回到函数A时候,栈帧B里保存的sp和fp寄存器所构造的另一个栈,就是栈帧A了。
所以,栈是链接起来的‘桢’的一个列表,按递减地址次序分配栈的每一块。寄存器 sp 总是指向在最当前桢中最低的使用的地址。ARM上栈有点奇葩。
其他CPU体系结构中说的SP栈指针,都是指向栈顶的,但是ARM的栈是自减栈,栈是向下生长的,也就是栈底处于高地址处,栈顶处于低地址处。有点奇葩和绕口。
栈还有另外一个用途就是进程切换。每个进程都有自己的系统栈空间,这个栈空间说的是内核栈,这个是在fork的时候就分配好的。所以,进程切换的时候,需要把前任的进程的上下文保存到前任进程的内核栈里。在每一个进程的生命周期中,必然会通过到系统调用陷入内核。在执行系统调用陷入内核之后,这些内核代码所使用的栈并不是原先进程用户空间中的栈,而是一个单独内核空间的栈,这个称作进程内核栈。进程跑在用户空间,需要一个栈,进程跑在内核空间也需要一个栈,所以这些栈的定义是不一样。
我们下一次在来和大家聊聊哪些“栈”谁的便宜。
最后一个问题,CPU上电时候第一条指令为什么要用汇编来实现?能不能让CPU第一条指令就执行C语言的代码?
能还是不能?为啥子嘛?
【[笨叔点滴3] “栈”谁便宜了()】
文章图片
推荐阅读
- [笨叔点滴2] 为啥子ARM32体系结构中每个处理模式都有一个单独的栈()
- GPU的工作原理(显卡和CPU的关系像“主仆”)
- 中信建投X袋鼠云(实时数仓,证券机构的“速度与稳定”)
- 果冻行业遭遇“寒冬”(全球畅销零食品牌利用数据提升市场竞争力)
- 数据库|教你用 docker 搞个网站
- 前端|VScode 主题和打字特效配置,让你的VScode活“”起来
- 我想谈一谈外包,请不要“妖魔化”它。
- 资讯|火爆全网的元宇宙、Web 3 和 NFT,如今已“过气”()
- Redis数据结构详解(3)-redis中的“排序好手”(跳表skiplist)
- 计算机|计算机界的最高奖项—“图灵奖”