有一次和女同学A吃饭,她带着小姑凉一块。在吃饭期间,同学给夹了块豆腐,小姑凉用天真无邪的眼神看着我:笨叔,你除了占我妈便宜,你还占过谁的便宜?  我顿时无语了。。。

上面是网上的一个小段子,生活里经常有人说谁谁占了谁的便宜?那计算机是不是也有占小便宜呢?计算机里还真有不少便宜可以“栈”,只不过不是“占”,而是各种形式的“栈”,不知道大家知不知道计算机里有多少个栈?比如说:

  1. 内核栈

  2. 中断栈

  3. 进程栈

  4. 线程栈

  5. 硬件栈

  6. 软件栈

  7. 堆栈

  8. 还有人占着茅坑

昨天我们聊了ARM32上或是奇葩或者先进的中断栈,我们今天继续来聊“栈”。

01 啥是栈

先看看啥是栈?栈的英文叫做stack。那中文里栈是怎么解释的呢?

1.储存货物或供旅客住宿的房屋:货栈|客栈。

2.养牲畜的竹、木栅栏:马栈。

那在计算机,它是啥呢,其实就是一个存放数据的数据结构类型。一种只能在一端进行插入和删除操作的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。看下面这个图应该比较清楚了。

这种数据结构的特点是 后入先出 (LIFO, Last In First Out),数据只能在串列的一端 (称为:栈顶 top) 进行 推入 (push) 和 弹出 (pop) 操作。向栈中存储数据称为PUSH,从栈中取数据称为POP。

大多数的处理器架构,都有实现硬件栈。有专门的栈指针寄存器,以及特定的硬件指令来完成 入栈/出栈 的操作。例如在 ARM 架构上,R13 (SP) 指针是堆栈指针寄存器,而 PUSH 是用于压栈的汇编指令,POP 则是出栈的汇编指令。

我们常常听人说,堆栈,那堆栈是个什么鬼?究竟是堆呢还是栈呢?其实堆栈本身就是栈,只是换了个抽象的名字,换了个马甲,有些人就昏了。

那堆是什么?在数据结构里,堆可以被看成是一棵树,如:堆排序。在操作系统里,堆是操作系统里管理内存的一种方式, 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。而栈,由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。

所以,堆和栈还有堆栈,他们三个是不是容易搞混了。

02 栈有啥子用嘛?

栈主要是有两大作用,一个是函数调用,另外一个是进程调度。

先说说函数调用。我们知道函数调用需要注意哪些东西?大家想到的可能是

  1. 参数怎么传

  2. 函数返回值怎么传

那在不同的计算机体系结构里,有不同的做法,但是他们相同的地方是一定会用到栈。

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] “栈”谁便宜了?相关推荐

  1. [笨叔点滴2] 为啥子ARM32体系结构中每个处理模式都有一个单独的栈?

    " 各位小伙伴,我是小笨叔.笨叔尽量每天给大家分享一点点小东西,可能是笨笨的.傻傻的.甜甜的.酸酸的小点滴,记录这每一刻每一天的小感悟,就像小雨点一样,它会慢慢汇合到大江大海!" ...

  2. [笨叔点滴6] 叔,这个git咋玩啊?

    "今天在食堂门口遇到了暗恋已久的女神,女神笑着给我递了张纸条就进食堂了,我打开纸条看到上面写的两个字"钙氧钨氧",我以为是瞎写的就扔了,晚上我睡觉时越想越不对劲,现在我肠 ...

  3. 水货笨叔介绍MCS锁

    前几天小明同学和笨叔抱怨:现在的spinlock锁的代码变得越来越复杂了,我都看不懂了.的确spinlock的代码从原来简单的几行代码,变成现在复杂的几百行,除了代码变得复杂,里面隐含的原理也不简单. ...

  4. ubantu 黑屏_死机黑屏专题上线啦,早鸟只要299,看完薪水翻一番

    全程约5小时高清,140多页ppt,8大实验,基于x86_64的Centos 7.6和arm64,提供全套实验素材和环境.全面介绍kdump+crash在死机黑屏方面的实战应用,全部案例源自线上云服务 ...

  5. 使用JLINK仿真器调试树莓派4

    学习armv8,怎么能没有开发板呢?有的小伙伴说,我可以用QEMU啊?笨叔要很负责任的说,QEMU不能100%地模拟armv8的硬件行为,有不少地方QEMU模拟不出来的,所以还是需要一个真实的硬件板子 ...

  6. 灵魂拷问之调度与切换十六问

    调度与切换之灵魂拷问,看看你大学学的操作系统课是否学到老师的真本领?没答对,说明你上课和笨叔一样睡觉,旷课,炒股,打游戏,和女同学聊天了 调度和切换的疑惑 有不少小伙伴问笨叔关于调度和切换的问题,在笨 ...

  7. linux6.5kdump,GitHub - figozhang/linux-5.0-kdump: Kdump+crash lab

    Linux 5.0 for Kdump+crash lab On ARM64 ============================================= 笨叔已经录制好视频课程节目,全 ...

  8. atmega8a如何烧写程序_如何让树莓派4上固件的debug日志输出到串口?

    第三季奔跑吧旗舰篇视频课程:arm64体系结构与编程2020年10月1号重磅上线笨叔带队,以练带学,几十个实验,等您来撸! 树莓派4上的FW 我们玩过树莓派的小伙伴都知道,树莓派4上有几个固件,我们是 ...

  9. Linux内存管理:ARM64体系结构与编程之cache(3):cache一致性协议(MESI、MOESI)、cache伪共享

    目录 为什么系统软件人员要深入了解cache? cache一致性协议 神马是MESI协议? MESI的操作 MESI状态图 演示:初始化状态为I的cache line 当本地CPU的缓存行状态为I时, ...

最新文章

  1. Reason not to use LINQ and reason to use
  2. 收益 or 挑战?Serverless 究竟给前端带来了什么
  3. Python学习笔记:网络编程
  4. 一文看懂Python(九)-----可变参数函数
  5. isFinite使用说明
  6. 每个程序员都必须搞懂的抽象类和接口的含义以及区别
  7. 使用MyBatis select数据库查出有数据 但返回对象为null时的解决办法
  8. Struts action-mapping 元素讲解
  9. java中实例化代码块_Java面向对象--代码块(初始化块)和内部类
  10. 货币代码(ISO 4217)
  11. 02 - i3wm 安装、配置TIM WeChat
  12. 100个替代昂贵商业软件的开源应用
  13. 《亲密关系》读书笔记
  14. CRM客户管理系统(Java)
  15. unable to find account data for the submitted AuthenticationToken
  16. 星际争霸十大挖掘性操作
  17. web前端介绍_html-超文本标记语言
  18. 外形很犀利 Win7旗舰版全新体验
  19. SpringCloud 微服务开放平台接口
  20. 二手交易平台毕业设计,校园二手物品交易平台毕业设计,二手交易网站设计与实现毕业设计分析

热门文章

  1. 修改过高分辨率导致显示器黑屏 - 解决之无脑篇
  2. 夕食の後のレギュラーエクスプレスについての議論(1)
  3. 软考:信息安全工程师5(应用安全)
  4. 【前端】语义化标签详解
  5. 3分钟整明白啥是 缓存雪崩
  6. 快速弄明白 Go 语言 GOPATH 设置
  7. Go语言系列-Go安装与配置
  8. посматрите!这里有一个新惊喜哦
  9. allegro如何制作Mark点并导入到PCB中
  10. 【番外】遇到autoCAD问题,大意失荆州,冒汗定位一星期