進程切換時是如何保存上下文的

前言

當前操作系統大部分採用分時的進程調度, 既每個進程運行一小段時間, 然後切換到下一個進程運行, 依次往復.

當進程運行的時候是獨佔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退出, 可恢復程序執行. 這自然是爲了鍵盤輸入這種中斷使用的.

總結

在看了這麼一份硬件文檔後, 硬件真的是做了很多事情, 很多軟件做不到的事情, 硬件來做, 軟件做的慢的事情, 硬件來做.

當然, 文檔中不止有這些內容,, 奈何我才疏學淺, 看英文文檔着實費盡. 罷了罷了, 解了心中疑惑便好...


原文地址: https://hujingnb.com/archives/782

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章