首先,PC的值为100,正在运行一个普通的用户程序的地址为100处的指令,CPU运行在用户态
接着开始进行系统调用,99,98,97三条指令分别准备内核进行该次调用所需要的一些参数
96为一条陷入指令,当CPU识别到陷入指令时,它会进行一个非常特殊的过程,有别于一般的PC+1和由正在运行的指令指出下一条指令所在的地址,这里发生的是CPU去内存(内核空间)查找一个在系统开机时便确定好的陷入表,根据之前准备环境时提供的参数与陷入表逐个对照,搜索下一次应该执行的指令地址。这里不由陷入指令给出下一次执行的地址的原因是:不管是系统调用函数的位置还是陷入表的位置都是内核空间,CPU想要访问内核空间必须先进入内核态。CPU在碰到陷入指令时,会做这么几件事:踢掉当前的用户程序(这个必须是第一个做的),进入内核态,查询陷入表,跳转到陷入表所指的系统调用的代码段地址(通过修改PC完成)。这里的四步缺一不可,而且顺序不能颠倒。我们来举几个反例:
假如在还没有踢掉用户程序的时候就进入内核态,那么这时候用户程序可能会做出一些不安全的行为;如果还没有进入内核态就去查询陷入表,这属于越权,是会引发异常的;如果某个鸡贼的用户程序设计者提前破译了某系统调用的地址甚至陷入表的地址,并且在自己的程序中设计一个跳转到该地址的指令,其实是不可行的,因为CPU还没有进入内核态。因此最关键的步骤控制就是一个:用户程序要想让CPU进入内核态,必须先放弃CPU的使用权
PC指向20,程序开始运行在内核空间
系统调用执行完毕,遇到了18地址的return from trap指令
CPU对return from trap指令的反应是:先退出内核态切回用户态,再将PC切到用户空间地址,出于安全性考虑这里同样必须先切换CPU状态才允许切换PC的值
【示意图】进行系统调用的过程
最新推荐文章于 2024-05-12 19:48:40 发布