Linux 中的各种栈:进程栈 线程栈 内核栈 中断栈

本文详细介绍了Linux中的栈,包括进程栈、线程栈、内核栈和中断栈的作用、内存位置以及它们在多任务和系统调用中的应用。栈作为一种数据结构在函数调用和多任务支持中起到关键作用,每个任务都有自己的栈空间,以实现任务之间的切换和上下文恢复。Linux内核区分不同类型的栈以确保系统稳定性和效率。
摘要由CSDN通过智能技术生成

栈是什么?栈有什么作用?

首先,栈 (stack) 是一种串列形式的 数据结构。这种数据结构的特点是 后入先出 (LIFO, Last In First Out),数据只能在串列的一端 (称为:栈顶 top) 进行 推入 (push) 和 弹出 (pop) 操作。根据栈的特点,很容易的想到可以利用数组,来实现这种数据结构。但是本文要讨论的并不是软件层面的栈,而是硬件层面的栈。

 

æ ç»æ

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

ARM 处理器拥有 37 个寄存器。 这些寄存器按部分重叠组方式加以排列。 每个处理器模式都有一个不同的寄存器组。 编组的寄存器为处理处理器异常和特权操作提供了快速的上下文切换。

提供了下列寄存器:
- 三十个 32 位通用寄存器:
- 存在十五个通用寄存器,它们分别是 r0-r12、sp、lr
- sp (r13) 是堆栈指针。C/C++ 编译器始终将 sp 用作堆栈指针
- lr (r14) 用于存储调用子例程时的返回地址。如果返回地址存储在堆栈上,则可将 lr 用作通用寄存器
- 程序计数器 (pc):指令寄存器
- 应用程序状态寄存器 (APSR):存放算术逻辑单元 (ALU) 状态标记的副本
- 当前程序状态寄存器 (CPSR):存放 APSR 标记,当前处理器模式,中断禁用标记等
- 保存的程序状态寄存器 (SPSR):当发生异常时,使用 SPSR 来存储 CPSR

上面是栈的原理和实现,下面我们来看看栈有什么作用。栈作用可以从两个方面体现:函数调用多任务支持

一、函数调用

我们知道一个函数调用有以下三个基本过程:
- 调用参数的传入
- 局部变量的空间管理
- 函数返回

函数的调用必须是高效的,而数据存放在 CPU通用寄存器 或者 RAM 内存 中无疑是最好的选择。以传递调用参数为例,我们可以选择使用 CPU通用寄存器 来存放参数。但是通用寄存器的数目都是有限的,当出现函数嵌套调用时,子函数再次使用原有的通用寄存器必然会导致冲突。因此如果想用它来传递参数,那在调用子函数前,就必须先 保存原有寄存器的值,然后当子函数退出的时候再 恢复原有寄存器的值

函数的调用参数数目一般都相对少,因此通用寄存器是可以满足一定需求的。但是局部变量的数目和占用空间都是比较大的,再依赖有限的通用寄存器未免强人所难,因此我们可以采用某些 RAM 内存区域来存储局部变量。但是存储在哪里合适?既不能让函数嵌套调用的时候有冲突,又要注重效率。

这种情况下,栈无疑提供很好的解决办法。一、对于通用寄存器传参的冲突,我们可以再调用子函数前,将通用寄存器临时压入栈中;在子函数调用完毕后,在将已保存的寄存器再弹出恢复回来。二、而局部变量的空间申请,也只需要向下移动下栈顶指针;将栈顶指针向回移动,即可就可完成局部变量的空间释放;三、对于函数的返回,也只需要在调用子函数前,将返回地址压入栈中,待子函数调用结束后,将函数返回地址弹出给 PC 指针,即完成了函数调用的返回;

于是上述函数调用的三个基本过程,就演变记录一个栈指针的过程。每次函数调用的时候,都配套一个栈指针。即使循环嵌套调用函数,只要对应函数栈指针是不同的,也不会出现冲突。

å½æ°æ ç»æ

 

函数调用经常是嵌套的,在同一时刻,栈中会有多个函数的信息。每个未完成运行的函数占用一个独立的连续区域,称作栈帧(Stack Frame)。栈帧存放着函数参数,局部变量及恢复前一栈帧所需要的数据等,函数调用时入栈的顺序为:

实参N~1 → 主调函数返回地址 → 主调函数帧基指针EBP → 被调函数局部变量1~N

栈帧的边界由 栈帧基地址指针 EBP 和 栈指针 ESP 界定,EBP 指向当前栈帧底部(高地址),在当前栈帧内位置固定;ESP指向当前栈帧顶部(低地址),当程序执行时ESP会随着数据的入栈和出栈而移动。因此函数中对大部分数据的访问都基于EBP进行。函数调用栈的典型内存布局如下图所示:

 

å½æ°è°ç¨æ çå¸ååå­å¸å±

更多关于 Linux后端开发网络底层原理知识学习提升 点击 学习资料 获取,完善技术栈,内容知识点包括Linux,Nginx,ZeroMQ,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值