IA-32 Intel手册学习笔记(三)任务切换
一個任務由兩部分組成
- 任務執行空間,由代碼段,棧段,和一個或多個數據段組成
- 任務狀態段(TSS)
如果操作系統使用處理器特權級機制,那么任務執行空間會對每個特權級提供不同的棧(實際上是對0, 1, 2三個特權級分別提供不同的棧)
注,用戶程序的特權級是3,不是上述三個棧中的任何一個,而是SS : ESP表示的棧
一個正在被執行的任務狀態包括
- 任務當前執行的空間,由各種段選擇子決定(CS, DS, SS, ES, FS和GS)。在線性地址空間中,是一個段空間
- 通用寄存器狀態,包括EAX, ECX, EDX, EBX, ESP, ESI和EDI的值
- EIP寄存器的狀態,即EIP的值
- CR3控制寄存器的值
- 任務寄存器(TR)的狀態
- LDTR寄存器的狀態
- I/O內存映射的基地址(包含在TSS中),(共享內存?)
- 三個棧指針,分別指向特權級0, 1, 2的棧地址
- 上一個被執行的任務的link(地址)
任務狀態中”上一個被執行的任務的link”指的是
當任務A使用CALL指令調用任務B時,在任務B的任務狀態中會包含任務A的地址,以便于當B執行完成后可以返回到任務A接著執行。很像匯編中CALL指令調用函數時將下一條語句的地址入棧。
軟件或者處理器可以使用以下幾種方法調度一個任務
- 顯式使用CALL指令調用某個任務
- 顯式使用JUMP指令跳轉到某個任務
- 由處理器隱式調用中斷處理任務
- 隱式調用異常處理任務(也是由處理器?)
- 如果EFLAGS寄存器的NT標志被設置,那么可以使用IRET指令在返回時隱式調轉到某個任務
上述的所有方法都是通過一個指向任務段描述符的選擇子或者指向任務門描述符的選擇子實現的。
在任務切換過程中,假設由于某種原因(通常是屬于某個任務的時間片用光),處理器將從當前正在執行的任務A切換到另一個任務B。此時,處理器需要記錄任務A的所有狀態以便當切換回任務A時就好像沒離開過一樣,所以,處理器會先將任務A的狀態(上面列出的任務狀態)存儲在任務A的TSS中(任務狀態段)。然后將任務A掛起,并將任務B的狀態加載到處理器上(從B的TSS中),以此完成任務切換。
雖然聽起來任務切換比較簡單,就是保存A,執行B。但是在這個看似簡單的過程中,處理器做了非常多的事情,不過再次之前,先看一下都在什么時候處理器會執行任務切換
- 當前任務A執行了JMP或CALL指令顯示調用任務B。JMP和CALL的操作數為段選擇子,指向GDT中任務B的TSS段描述符
- 當前任務A執行了JMP或CALL指令顯示調用任務B。JMP和CALL的操作數為段選擇子,指向GDT或任務B的LDT中的任務門描述符
- 當前任務A出現一個指向IDT中任務門描述符的中斷/異常向量
- 當前任務A執行了IRET指令且EFLAGS寄存器中的NT標志位被設置
當發生任務切換時,處理器依次執行如下操作
任務門描述符提供對TSS的間接引用,可以位于GDT,LDT以及IDT中,描述符中保存著段選擇子,通過段選擇子,可以在GDT中找到TSS段描述符以獲取TSS的基地址
當程序使用CALL或JMP指令嘗試條用任務門時,CALL和JMP的操作數實際上是任務門的選擇子,通過選擇子可以找到在GDT,LDT或IDT中的任務門描述符。不過,任務門選擇子的CPL和RPL必須小于等于門描述符的DPL
任務門描述符的結果如下
TSS(任務狀態段)的結果如下
可以看出TSS中主要就是各種寄存器的值,這主要是為了當任務切換時,把當前正在執行的任務的各種狀態保存下來,這樣,當又執行這個任務時,就可以從TSS中獲取剛離開時這個任務的狀態,從而像從沒有離開過一樣。
每個任務都有屬于自己的TSS,而TR寄存器保存著當前正在執行的任務的TSS的段選擇子和基地址以及偏移量。
在執行任務A時,TR寄存器保存著任務A的TSS的段選擇子和基地址。當處理器從任務A切換到任務B時,處理器執行如下操作
TR寄存器結果如下
總結
以上是生活随笔為你收集整理的IA-32 Intel手册学习笔记(三)任务切换的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 每天一道LeetCode-----给定一
- 下一篇: 每天一道LeetCode-----生命游