• 编程-函数栈与进程栈


     
    一. 代码编程极简进化史
    从纸带上的机器码,到汇编语言算是比较自然而然的变化。因为汇编语言每一条指令即对应着一条机器指令码。汇编中的jump和branch为代码模块化组织提供了最原始的形式。
    从汇编语言到C语言算是又一个比较自然的进一步简化,因为C语言是过程式。而相较于汇编的jump/branch,C语言的函数调用(function call)算是带领代码模块化组织形式走出了石器时代。
    后续的面向对象语言,也是基于function call, 只是编译器会自动生成constructor/destructor。但正如函数调用的概念,为面向对象提供了基础一样,基于function call和function generate的面向对象语言,也提供了很新的代码组织形式和新的想象,带领编程走进了现代化。
     
    二. 函数栈
    程序 = 算法 + 数据。
    算法的承载为一条条指令;数据的承载即是寄存器和内存,为指令操作的直接对象。
    相较于汇编语言只使用寄存器即可执行运算,并跳来跳去。C语言并不以寄存器为直接操作对象,而是内存中的一个一个变量。
    相较于汇编语言jump/branch时,依赖于LR寄存器记录跳转指令下一条指令的地址,然后才能跳回来,C语言的function call则依赖于编译器根据ABI中规定的参数寄存器和返回值寄存器,以及栈来存储函数临时变量和函数的返回地址;
     
    每个函数占用的栈区间,我们成为函数的栈帧,栈帧的内容为:
    1. 函数用到的临时变量;
    2. 函数的返回地址;
    函数调用一层层进行下去,栈里的内容即为一层层函数调用的栈帧,即为函数栈。
     
    下面举例说明。
    int __add(int a, int b)
    {
        return a + b;
    }
    
    int add(int a, int b)
    {
        return __add(a, b);
    }
    
    int main(void) {
      volatile int i = 0;
    
      int v = add(1, 3);
      
      /* Loop forever */
      for (;;) {
        i++;
      }
    }
    函数add,基于PowerPC VLE的汇编代码如下:
    其中,mflr r0把存有函数返回地址的lr寄存器的值存入r0,然后se_stw r0,36(rsp)把返回地址写入栈;函数返回时,se_lwz r0,36(rsp)从栈中读取函数返回地址,然后se_mtlr r0把返回地址写入lr,然后blr返回到lr指定的地址处执行,即上一层函数调用本函数的下一条指令处执行。
     
    Java里面Exception的printStackTrace()打印出的一层层函数调用栈是函数栈最明显的例子。Linux Kernel panic时也会打印函数调用栈,以及栈帧的内容,可以观察临时变量和返回地址。
     
    三. 进程栈
    进程栈存储进程的调用关系吗?不是,进程没有调用关系。
    进程栈存储进程的父子关系吗?不是,父子进程之间也没有调用关系。
     
    进程栈存储进程的抢占关系,高优先级进程抢占低优先级进程时,则需要把低优先级进程的Context存储起来,以便后续恢复。另一种情况是,中断打断当前进程时,也需要存储当前进程的Context。
     
    进程上下文存储的内容:
    1.进程的函数调用栈;
    2.进程的状态,Task Control Block(TCB),包括进程使用的寄存器的当前值;
     
    每个进程都会分配专属的栈空间,以存储该进程的上下文。需要恢复时,即从该进程的上下文中恢复各个寄存器的值,接着被抢占时的位置继续执行。
     
    四. 对比
    由此可以看出,进程栈是指进程的栈,而非函数栈那样,存放一层层函数调用的栈帧。多个进程的栈是离散的,分开的,而非像函数栈那样连续存放。
  • 相关阅读:
    Kubernetes1.91(K8s)安装部署过程(一)--证书安装
    开源仓库Harbor搭建及配置过程
    有关centos7 图形化root用户登录
    linux服务器查看tcp链接shell
    django表格form无法保存评论排查步骤
    Redis 4.x 安装及 发布/订阅实践和数据持久化设置
    django博客项目-设置django为中文语言
    windows 环境下如何使用virtualenv python环境管理工具
    【转载】python中利用smtplib发送邮件的3中方式 普通/ssl/tls
    php安装phpize工具
  • 原文地址:https://www.cnblogs.com/wjcdx/p/9246549.html
Copyright © 2020-2023  润新知