当前位置: 首页 > article >正文

OS_过程调用与系统调用

2024.06.25:操作系统过程调用与系统调用学习笔记

第5节 过程调用与系统调用

  • 5.1 过程调用/函数调用/子程序调用
  • 5.2 系统调用
    • 5.2.1 系统调用汇编层
  • 5.3 过程调用与系统调用的对比


5.1 过程调用/函数调用/子程序调用

过程调用)也称为(函数调用)或(子程序调用),它允许程序代码被组织成(),每个块完成特定的任务,这些块可以在程序的多个地方调用。

在这里插入图片描述

过程调用既然是调用,那就一定会有一个(过程P:调用者caller)和一个(过程Q:被调用者callee


过程调用可以简单归纳总结成6步
在这里插入图片描述

  • P将入口参数放在Q能访问的到的地方

第一次:此时,P这里指的是main函数,Q指的是caller函数,如果被调用的这个函数Q是有参数的,那参数到底传给谁,是由调用者的函数决定的,因此调用者的函数应当将这个参数放在被调用的这个函数可以访问到的地方
第二次:caller函数应该把add需要用到的这些参数放到add函数可以访问到的地方,这个参数的值还是压到caller的栈帧中,注意add函数看似不访问caller的局部变量区,实际上它还是会有一些区域是这个add函数可以访问到的,它会被叫作(参数调用区)。我们现在会通过两个寄存器的中转,把这两个局部变量先复制到这两个寄存器中,然后再压回到caller的栈帧中(圈起来的区域是局部变量区,蓝色区域是参数调用区)在这里插入图片描述

  • P将返回地址存到特定的地方,然后将控制转移到Q

第一次:假设调用caller()函数的过程是main(),caller()函数没有参数,所以直接保存main函数的返回地址,控制转移到caller()在这里插入图片描述
第二次在这里插入图片描述

  • Q保存P的现场,并为自己的非静态局部变量分配空间
  • 被调用者caller应该去保存调用它的函数main函数它的现场,由于这个代码里面没有体现main函数,所以就不去考虑这个。
  • Q,也就是caller函数应该为自己的非静态局部变量去分配空间,比如这里的temp1,temp2,sum等

在这里插入图片描述
在这里插入图片描述

  • 执行Q的过程体

现在add这个函数的起始地址改到PC里面,这样我们就可以根据PC去执行add这个函数,add函数内部并没有什么含金量,就是直接去返回一个两个参数的求和,规定这个值一定会放在EAX这个寄存器中,通过中转把EAX这个结果写回到caller的栈帧中局部变量sum的这个位置在这里插入图片描述

  • Q恢复P的现场,并释放局部变量所占空间

add函数执行完之后会将结果放到EAX寄存器再复制到栈里面去,此时add函数调用已经结束了,然后add函数会执行ret指令,ret指令会做两件事情,首先它会让栈帧里面的这个返回地址出栈,出栈之后,返回地址弹出这个值写回PC里面,PC带领CPU回到caller函数,也就相当于caller的栈帧被清理了在这里插入图片描述

  • Q取出返回地址,将控制转移到P

主存里面有一个区域叫作堆栈(一个堆区、一个栈区),对于()来说,它的特性就是从高地址往低地址去增长的,并且它满足数据结构我们学过的这个栈的特性(先进后出)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


5.2 系统调用

系统调用的引用是因为用户程序想要去申请操作系统它的服务,操作系统的核心服务放在操作系统的内核部分,而操作系统内核常驻在内存的某一个区域中。

比如说你的一个用户进程想要去读写某个文件,这个用户进程其实是没有权限去执行这个指令的,关于所有的文件管理它都是由内核去进行的,所以此时必须要专区执行内核的代码。

但是我们知道CPU有两种工作状态,在用户态下去执行用户程序的时候,是没有办法去访问到操作系统的内核去代码,此时我们就需要CPU转到内核态,从而它就可以去访问到操作系统内核的代码,完成我们想要的操作,这个就是系统调用


系统调用既然需要CPU变态,那它就需要通过一个软中断指令,这个软中断并不会显示地出现在用户程序里
在这里插入图片描述


5.2.1 系统调用汇编层

在这里插入图片描述


5.3 过程调用与系统调用的对比

  1. 过程调用没有引发中断,而系统调用是通过发起一个软中断实现调用OS内核代码的
  2. 过程调用在调用时只需要保存PC而不需要保存PSW,而系统调用需要正常地进行(内部)中断处理,因此需要保存PC和PSW
  3. 过程调用全程CPU都处于同一个工作模式,即用户态或内核态,而系统调用会导致CPU从用户态切换内核态
  4. 过程调用的被调用函数会出现在代码中,而系统调用一个库函数即可实现,操作系统内核的代码不会出现在程序代码中
  5. 过程调用通过CALL或JMP指令进入,而系统调用通过INT或TRAP指令进入
  6. 过程调用是可以嵌套的,而系统调用一般不允许发生嵌套或递归

http://www.kler.cn/news/340459.html

相关文章:

  • 位运算 -- 力扣
  • Springboot 文件上传
  • 海洋鱼类图像分类分割系统源码&数据集分享
  • MySQL进阶 - 索引
  • SpringIoC容器的初识
  • 软件验证与确认实验二-单元测试
  • YOLO11改进 | 卷积模块 | 轻量化GSConv替换普通的conv
  • NLP: SBERT介绍及sentence-transformers库的使用
  • Spring Boot大学生就业招聘系统的开发策略
  • 基于SSM的家庭理财系统的设计与实现
  • 掌握 ASP.NET Web 开发:从基础到身份验证
  • 【Java 并发编程】解决多线程中数据错乱问题
  • 前端vue-安装pinia,它和vuex的区别
  • Vue中watch监听属性的一些应用总结
  • 微信小程序启动不起来,报错凡是以~/包名/*.js路径的文件,都找不到,试过网上一切方法,最终居然这么解决的,【避坑】命运的齿轮开始转动
  • 【Linux】man手册安装使用
  • 以一个B站必剪应用Bug过一下CVSS 4.0评分
  • TCP网络通信——多线程
  • 重学SpringBoot3-集成Redis(二)之注解驱动
  • 408算法题leetcode--第26天