[笨叔点滴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体系结构中每个处理模式都有一个单独的栈?
" 各位小伙伴,我是小笨叔.笨叔尽量每天给大家分享一点点小东西,可能是笨笨的.傻傻的.甜甜的.酸酸的小点滴,记录这每一刻每一天的小感悟,就像小雨点一样,它会慢慢汇合到大江大海!" ...
- [笨叔点滴6] 叔,这个git咋玩啊?
"今天在食堂门口遇到了暗恋已久的女神,女神笑着给我递了张纸条就进食堂了,我打开纸条看到上面写的两个字"钙氧钨氧",我以为是瞎写的就扔了,晚上我睡觉时越想越不对劲,现在我肠 ...
- 水货笨叔介绍MCS锁
前几天小明同学和笨叔抱怨:现在的spinlock锁的代码变得越来越复杂了,我都看不懂了.的确spinlock的代码从原来简单的几行代码,变成现在复杂的几百行,除了代码变得复杂,里面隐含的原理也不简单. ...
- ubantu 黑屏_死机黑屏专题上线啦,早鸟只要299,看完薪水翻一番
全程约5小时高清,140多页ppt,8大实验,基于x86_64的Centos 7.6和arm64,提供全套实验素材和环境.全面介绍kdump+crash在死机黑屏方面的实战应用,全部案例源自线上云服务 ...
- 使用JLINK仿真器调试树莓派4
学习armv8,怎么能没有开发板呢?有的小伙伴说,我可以用QEMU啊?笨叔要很负责任的说,QEMU不能100%地模拟armv8的硬件行为,有不少地方QEMU模拟不出来的,所以还是需要一个真实的硬件板子 ...
- 灵魂拷问之调度与切换十六问
调度与切换之灵魂拷问,看看你大学学的操作系统课是否学到老师的真本领?没答对,说明你上课和笨叔一样睡觉,旷课,炒股,打游戏,和女同学聊天了 调度和切换的疑惑 有不少小伙伴问笨叔关于调度和切换的问题,在笨 ...
- linux6.5kdump,GitHub - figozhang/linux-5.0-kdump: Kdump+crash lab
Linux 5.0 for Kdump+crash lab On ARM64 ============================================= 笨叔已经录制好视频课程节目,全 ...
- atmega8a如何烧写程序_如何让树莓派4上固件的debug日志输出到串口?
第三季奔跑吧旗舰篇视频课程:arm64体系结构与编程2020年10月1号重磅上线笨叔带队,以练带学,几十个实验,等您来撸! 树莓派4上的FW 我们玩过树莓派的小伙伴都知道,树莓派4上有几个固件,我们是 ...
- Linux内存管理:ARM64体系结构与编程之cache(3):cache一致性协议(MESI、MOESI)、cache伪共享
目录 为什么系统软件人员要深入了解cache? cache一致性协议 神马是MESI协议? MESI的操作 MESI状态图 演示:初始化状态为I的cache line 当本地CPU的缓存行状态为I时, ...
最新文章
- Reason not to use LINQ and reason to use
- 收益 or 挑战?Serverless 究竟给前端带来了什么
- Python学习笔记:网络编程
- 一文看懂Python(九)-----可变参数函数
- isFinite使用说明
- 每个程序员都必须搞懂的抽象类和接口的含义以及区别
- 使用MyBatis select数据库查出有数据 但返回对象为null时的解决办法
- Struts action-mapping 元素讲解
- java中实例化代码块_Java面向对象--代码块(初始化块)和内部类
- 货币代码(ISO 4217)
- 02 - i3wm 安装、配置TIM WeChat
- 100个替代昂贵商业软件的开源应用
- 《亲密关系》读书笔记
- CRM客户管理系统(Java)
- unable to find account data for the submitted AuthenticationToken
- 星际争霸十大挖掘性操作
- web前端介绍_html-超文本标记语言
- 外形很犀利 Win7旗舰版全新体验
- SpringCloud 微服务开放平台接口
- 二手交易平台毕业设计,校园二手物品交易平台毕业设计,二手交易网站设计与实现毕业设计分析