进程切换时是如何保存上下文的

前言

当前操作系统大部分采用分时的进程调度, 既每个进程运行一小段时间, 然后切换到下一个进程运行, 依次往复.

当进程运行的时候是独占CPU的, 此时操作系统是无法强行介入的, 为了将执行权让出来, 就需要硬件的配合了. 硬件每个一个时钟周期(比如10ms), 就会产生一个时钟中断, 而这个时钟中断会将执行权强行交给操作系统的调度进程, 然后由调度进程进行后续处理.

以上, 就是我在第一遍看操作系统时留下的印象, 但有几个问题当时没有搞明白:

  1. 如何保存进程的上下文? 在将进程暂停后, 为了之后再次运行, 需要将运行现场保存起来, 以便再次运行时恢复. 而在CPU的角度, 运行现场其实就是几个寄存器的值. 想标志寄存器/通用寄存器/段寄存器等等, 调度进程都能拿到, 我都能理解. 但是, 指令寄存器 PC如何保存呢? 当执行权交给调度进程后, PC自然也就指向了调度进程, 已经丢失了当时的值.
  2. 若在调度进程运行时, 再次发生了时钟中断, 不就陷入死循环了.

以上问题, 在多年后我再次重翻操作系统时, 得到了解答.

解惑

如何保存上下文

其实, 前面的分析是没错的, 当执行进程切换后, 指令寄存器的值必然指向当前执行的进程. 既然软件办不到, 那就硬件来做咯.

找到了这样一篇CPU文档 (可能和现在主流 CPU 实现有所差异, 不过作为参考倒是问题不大):

image-20220522122614103

当触发中断时, 会将PC, X, A, CC寄存器的值保存到栈中. 其中X A是通用寄存器, CC是一个条件码寄存器, 在文档的5.1小节对这些寄存器均有介绍.

哎, 这不就解决了切换后的上下文问题么.

中断嵌套问题

当调度程序正在运行时, 再次发生中断怎么办? 如果能将中断关闭, 不就没人来打扰了么.

没错, 就是这么干. 通过修改CC寄存器的值, 可以达到关闭中断的效果.

image-20220522124633656

同时也提供了中断操作的汇编指令.

image-20220522125215878

至此, 中断的嵌套问题便解决了.

并且中断程序结束后, 调用IRET退出, 可恢复程序执行. 这自然是为了键盘输入这种中断使用的.

总结

在看了这么一份硬件文档后, 硬件真的是做了很多事情, 很多软件做不到的事情, 硬件来做, 软件做的慢的事情, 硬件来做.

当然, 文档中不止有这些内容,, 奈何我才疏学浅, 看英文文档着实费尽. 罢了罢了, 解了心中疑惑便好…

订阅评论
提醒
guest
0 评论
内联反馈
查看所有评论
0
希望看到您的想法,请发表评论。x