多工處理
工作切換
進行工作切換
處理器在進行工作切換時,會進行很多步驟。簡單的說,大略是:
-
檢查是否有權切換到目標工作。
-
檢查目標工作的 TSS 是否正確。
-
檢查目標工作是否可用(是否存在或是否忙碌)。
-
設定或清除目前工作的相關旗標(包括 TSS descriptor 中的 B 旗標和 EFLAGS
中的 NT 旗標)。
-
將目前的狀態存放到目前的 TSS 中。
-
設定或清除新工作的相關旗標(包括 TSS descriptor 中的 B 旗標、TSS 中的 CR0
的 TS 旗標、和 EFLAGS 中的 NT 旗標)。
-
將新工作的 TSS descriptor 載入到 TR 中。
-
載入新工作的 TSS 中存放的狀態。
-
開始執行新工作。
如果新工作是由 CALL 指令、或是中斷/例外產生的,則新工作會記錄上一個工作的位址,而且上一個工作的
B(忙碌)旗標也不會被清除(若使用 JMP 指令跳到新工作中,則舊工作的 B 旗標會被清除)。而且處理器會將
EFLAGS 中的 NT(Nested-task)旗標設為 1,表示目前是在「巢狀」的工作中。當工作使用
IRET 離開時,處理器會從 TSS 中取出上一個工作的位址,回到上一個工作。如果是用
JMP 指令執行新工作,則 NT 旗標會被設為 0。
因為一個工作只有一份 TSS,所以工作是不能遞迴呼叫的(否則會破壞 TSS
中原先存放的資料)。處理器利用 B 旗標來判斷是否有遞迴呼叫一個工作。因此,當工作一直連結下去時(例如,工作A呼叫工作B,工作B又呼叫工作C),就可以避免連結中的任何一個工作又被呼叫一次,而導致錯誤。