2015-02-12 69 views
0

我正在閱讀Nick Blundell編寫的「從頭開始編寫操作系統」一書。在其中一章中,解釋了我們如何從16位模式轉換爲32位模式。它說,在轉移到32位模式之前,我們應該確保所有在16位模式下的指令都在流水線內(CPU內部的指令流水線)執行。爲了實現這一點,它說,我們應該做出一個遠大的跳躍,導致管道沖洗,書中說這是完成目前在管道不同階段的所有指令。
但是我對流水線刷新的理解是刪除了由於程序流程改變而導致的來自指令流水線的條件分支之後的所有指令。
我對這些描述感到困惑,有人可以解釋在管道沖洗過程中發生了什麼。
此外,這本書說近旁跳可能不足以做管道沖洗。我也不明白這一點。x86從16位轉換到32位模式

回答

3

只要不執行那些指令,管道清洗就需要從管道清空預取和解碼/轉換的指令。這是在條件跳轉之後以及轉換到指令集必須使用與16位實模式不同的邏輯進行解碼的段之後所必需的。可用操作碼,分段模型和默認操作數/地址大小前綴位(僅舉幾例)可能存在差異。

有可能在處理器中優化近跳轉以便在解碼後立即從某個地址開始預取指令;實際上近遠跳變的唯一區別在於CS的顯式重載(並且設置了用於指令解碼的新策略),這可能被設計爲觸發流水線沖洗。

1 [在86跳轉指令] 1

if(IsNearJump()) { 
    if(IsRelativeJump()) TemporaryEIP = EIP + Destination; //EIP is instruction following JMP instruction; 
    else TemporaryEIP == Destination; 
    if(!IsWithinCodeSegmentLimits(TemporaryEIP)) Exception(GP(0)); 
    if(OperandSize == 32) EIP = TemporaryEIP; 
    else EIP = TemporaryEIP & 0xFFFF; //OperandSize == 16 
    //END 
} 
if(IsFarJump() && (PE == 0 || (PE == 1 && VM == 1)) { //real-address or virtual-8086 mode 
    TemporaryEIP = Destination.Offset; //Destination is ptr16:32 or [m16:32] 
    if(!IsWithinCodeSegmentLimits(TemporaryEIP)) Exception(GP(0)); 
    CS = Destination.SegmentSelector; //Destination ptr16:32 [m16:32] 
    if(OperandSize == 32) EIP = TemporaryEIP; //Destination ptr16:32 [m16:32] 
    else /*OperandSize == 16*/ EIP = TemporaryEIP & 0xFFFF; //clear upper 16 bits; 
    //END 
} 
+0

謝謝....但如果管道沖洗只能從管線中移除的說明,爲什麼書上說,它完成當前管道中的所有指令。 – sarthak 2015-02-12 07:54:30

+0

管道沖洗AFAIK,必須意味着只清除管道中的_invalid_或潛在無效的指令。但是管道中也有有效的指示,這些指示意味着要完成。一種純粹推測的方法是,遠程調用將一個標識放置到流水線上,這實際上完成了所有指令直到遠程調用,將所有其他指令標記爲無效,並開始用與該流水線關聯的微代碼填充流水線遠調用。 – 2015-02-12 08:42:47