1. 程式人生 > >處理器體系結構

處理器體系結構

處理器體系結構

指令集Y86-64暫存器

Y86-64處理器每個時鐘週期執行一條完整的Y86-64指令。

X86-64暫存器有

程式設計師可見的狀態的暫存器:

Y86-64的狀態類似於x86-64。有15個程式暫存器:%rax,%rcx,%rdx,%rbx,%rsp,%rbp,%rsi,%rdi和%r8到%r14。這裡省略了%r15以簡化指令的編碼。

其中%rsp被入棧、出棧、呼叫和返回指令作為棧指標。

有3個一位的條件碼:ZF,SF和OF,它們儲存著最近的算術或邏輯指令所造成影響的有關資訊。

程式計數器(PC)存放當前正在執行指令的地址。

Y86-64程式用虛擬地址來引用記憶體位置。

程式狀態的最後一個部分是狀態碼Stat,它表明程式執行的總體狀態。它會指示是正常執行,還是出現了異常。

Y86-64指令

Y86-64指令集基本上是x86-64指令集的一個子集。它包括8位元組整數操作,定址方式較少,操作也較少。

Y86-64的一些細節

X86-64的movq指令分成了4個不同的指令:irmovq,rrmovq,mrmovq和rmmovq分別顯示地指明源和目的的格式。源可以是立即數(i),暫存器(r)或記憶體(m)。指令名字的第一個字母表明瞭源的型別。目的可以是暫存器(r)或記憶體(m)。指令民資的第二個字母表明瞭目的的型別。在決定如何實現資料傳送時,顯示地指令資料傳送這4中型別是很有幫助的。

    兩個記憶體傳送指令中的記憶體引用方法是簡單的基址和偏移量形式。在地址計算中,我們不支援第二變址暫存器(second index register)和任何暫存器值的伸縮(scaling)。

    同x86-64一樣,我們不允許一個記憶體地址直接傳送到另一個記憶體地址。另外,也不允許將立即數傳送到記憶體。

    有4個整數操作指令,Opq。它們是addq,subq,andq和xorq。它們只對暫存器資料進行操作,而x86-64還允許對記憶體資料進行這些操作。這些指令會設定3個條件碼ZF,SF和OF(零,符號和溢位)。

    7個跳轉指令(jxx)是jmp,jle,jl,je,jne,jge和jg。根據分支指令的型別和條件程式碼的設定來選擇分支。

    有6個傳送指令(cmovXX):cmovele,cmovl,cmove,cmovne,cmovge和cmovg。這些指令的格式與暫存器-暫存器傳送指令rrmovq一樣,但是隻有當條件碼滿足所需要的約束時,才會更新目的暫存器的值。

    call指令將返回地址入棧,然後跳到目的地址。ret指令從這樣的呼叫中返回。

    Pushq和popq指令實現了入棧和出棧,就像在x86-64中一樣。

    halt指令停止指令的執行。X86-64中有一個與之相當的指令hlt。X86-64的應用程式不允許使用這條指令,因為它會導致整個系統暫停執行。對於Y86-64來說,執行halt指令會導致處理器停止,並將狀態碼設定為HLT。

指令編碼

每條指令需要1~10個位元組不等,這取決於需要哪些欄位。每條指令的第一個位元組表明指令的型別。這個位元組分為兩個部分,每部分4位:高4位是程式碼(code)部分,低4位是功能(function)部分。功能值只有在一組相關指令公用一個程式碼時才有用。

15個程式暫存器中每個都有一個相應的範圍在0到0xE之間的暫存器識別符號(register ID)。Y86-64中的暫存器編號跟x86-64中的相同。程式暫存器存在CPU中的一個暫存器檔案中,這個暫存器檔案就是一個小的,以暫存器ID作為地址的隨機訪問儲存器。在指令編碼中以及在我們的硬體設計中,當需要指令不應訪問任何暫存器時,就用ID值0xF來表示

    有的指令只有一個位元組長,而有的需要運算元的指令編碼就更長一些。首先,可能有附加的暫存器指示符位元組(register specifier byte),指定一個或兩個暫存器。這些暫存器欄位稱為rA和rB。根據指令型別,指令可以指定用於資料來源和目的暫存器,或是用於地址計算的基址暫存器。沒有暫存器運算元的指令,例如分支指令和call指令,就沒有暫存器指示符位元組。哪些只需要一個暫存器操作的指令(irmovq,pushq和popq)將另一個暫存器指示符設為0xF。

    有些指令需要一個附加的4位元組常數字(constant word)。這個字能作為irmovq的立即數資料,rmmovq和mrmovq的地址指示符的偏移量,以及分支指令和呼叫指令的目的地址。

    分支指令和呼叫指令的目的是一個絕對地址,不想IA32中那樣使用PC(程式計數器)相對定址方式。處理器使用PC相對定址方式,分支指令的編碼會更簡潔。

    同IA32一樣,所有整數採用小端法編碼。

Eg:rmmovq %rsp,0x12345678abcd(%rdx)的位元組編碼。從上圖中偶爾們可以看到rmmovq的第一個位元組為40。源暫存器%rsp應該編碼放在rA欄位中,而基地址暫存器%rdx應該編碼放在rB欄位中。得到暫存器指示符42。最後,偏移量放在8位元組的常數字中。首先在0x123456789abcd的前面填充上0變成8個位元組,變成位元組序列00 01 23 45 67 89 ab cd。寫成按位元組反序就是cd ab 89 67 45 23 01 00。將它們都連線起來就得到指令的編碼4041cdab896745230100。

Y86-64異常

    對於Y86-64來說,程式設計師課件的狀態包括狀態碼Stat,它描述程式執行的總體狀態。這個程式碼可能的值如下圖:

程式碼值1,命名為AOK,表示程式執行正常,

程式碼值2,命名HLT,表示處理器執行了一條halt指令

程式碼值3,命名為ADR,表示處理器試圖從一個非法記憶體地址讀或者向一個非法記憶體地址寫。

程式碼值,命名為INS,表示遇到了非法的指令程式碼。

Y86-64程式

    X86-64程式是由GCC編譯器產生的。Y86-64程式碼與之類似但有以下不同點:

    Y86-64將常數載入到暫存器,因為它在算術指令中不能使用立即數。

    要實現從記憶體讀取一個數值並將其餘一個暫存器相機,Y86-64程式碼需要兩條指令,而x86-64只需要一條addq指令。

程式的完整編碼

 

Y86-64的順序實現

取值(fetch):取指階段從記憶體讀取指令位元組,地址為程式計數器PC的值。從指令中抽取出指令指示符位元組的兩個四位部分,稱為icode(指令程式碼)和ifun(指令功能)。它可能取出一個暫存器指示符位元組,指明一個或兩個暫存器運算元指示符rA和rB。它還可能取出一個四位元組常數字valC。它按順序方式計算當前指令的下一條指令的地址valP。也就是說,valP等於PC的值加上已取出指令的長度。

譯碼(decode):譯碼階段從暫存器檔案讀入最多兩個運算元,得到值valA和/或valB。通常,它讀入指令rA和rB欄位指明的暫存器,不過有些指令時暫存器%rsp的。

執行(execute):在執行階段,算術/邏輯單元(ALU)要麼執行指令指明的操作(根據ifun的值),計算記憶體引用的有效地址,要麼增加或減少棧指標。得到值,我們稱為valE。在此,也可以設定條件碼。對一條條件傳送指令來說,這個階段會檢查條件碼和傳送條件,如果條件成立,則更新目標暫存器,同樣,對一條跳轉指令來說,這個階段會決定是不是應該選擇分支。

訪存(memory):訪存階段可以將資料寫入記憶體,或者從記憶體讀出資料。讀出的值為valM。

寫回(write back):寫回階段最多可以寫兩個結果到暫存器檔案。

更新PC(PC update):將PC設定成下一條指令的地址。

 

 

SEQ硬體結構

實現所有Y86-64指令需要的計算可以被組織成6個基本階段:取值,譯碼,執行,訪存,寫回和更新PC。下圖給出了一個能執行這些操作的抽象表示:

取值:將程式計數器暫存器作為地址,指令記憶體讀取指令位元組。PC增加器(PC incrementer)計算valP,即增加了的程式計數器。

譯碼:暫存器檔案有兩個讀埠A和B,從這兩個埠同時讀暫存器值valA和valB。

執行:執行階段會根據指令的型別,將算術/邏輯單元(ALU)用於不同的目的。對整數操作,它要執行指令所指定的運算。對其他指令,它會作為一個加法器來計算增加或減少棧指標,或者計算有效地址,或者只是簡單地加0,將一個輸入傳遞到輸出。條件碼暫存器(CC)有三個條件碼位。ALU負責計算條件碼的新值。當執行條件傳送指令時,根據條件碼和傳送條件來計算決定是否更新目標暫存器。同樣,當執行一條跳轉指令時,會根據條件碼和跳轉型別來計算分支訊號Cnd。

訪存:在執行訪存操作時,資料記憶體讀出或寫入一個記憶體字。指令和資料記憶體訪問的是相同的記憶體位置,但是用於不同的目的。

寫回:暫存器檔案有兩個寫埠。埠E用來寫ALU計算出來的值,而埠M用來寫從資料記憶體中讀出的值。

PC更新:程式計數器的新值選擇自:valP,下一條指令的地址;valC,呼叫指令或跳轉指令指定的目標地址;valM,從記憶體讀取的返回地址。

取指階段

譯碼和寫回階段

執行階段

訪存階段

 

 

訪問主存

Movq A,%rax

地址請A的內容被載入到暫存器%rax中。CPU晶片上稱為匯流排介面(bus interface)的電路在總線上發起讀事務。讀事務是由三個步驟組成的。首先,CPU將地址A放到系統總線上。I/O橋將訊號傳遞到記憶體匯流排。接下來,主存感覺到記憶體總線上的地址訊號,從記憶體匯流排讀地址,從DRAM取出資料字,並將資料寫到記憶體匯流排。I/O橋將記憶體匯流排訊號翻譯成系統匯流排訊號,然後沿著系統匯流排傳遞。最後CPU感覺到系統總線上的資料,從總線上讀資料,並將資料複製到暫存器%rax。

 

匯流排結構示例

訪問磁碟

    CPU使用一種稱為記憶體對映I/O(memory-mapped I/O)的技術來向I/O裝置發射命令。在使用記憶體對映I/O的系統中,地址空間中有一塊地址是為與I/O裝置通訊保留的。每個這樣的地址稱為一個I/O埠(I/Oport)。當一個裝置連線到匯流排時,它與一個或多個埠相連(或它被對映到一個或多個埠)。

    來看一個簡單的例子,假設磁碟控制器對映到埠Oxa0。隨後,CPU可能通過執行三個對地址Oxa0的儲存指令,發起磁碟讀:第一個指令是傳送一個命令字,告訴磁碟發起一個讀,同時還發送了其他的引數,例如當讀完成時,是否中斷CPU。第二個指令指令應該讀的邏輯塊號。第三條指令指明應該儲存磁碟扇區內容的主存地址。

    在磁碟控制器收到CPU的讀命令之後,它將邏輯塊號翻譯成一個扇區地址,讀該扇區的內容,然後將這些內容直接傳送到主存,不需要CPU的干涉。裝置以自己執行讀或者寫匯流排事務而不需要CPU干涉的過程,稱為直接記憶體訪問(Direct Memory Access,DMA)。這種資料傳送稱為DMA傳送(DMA transfer)。

    在DMA傳送完成,磁碟扇區的內容被安全地儲存在主存中以後,磁碟控制器通過給CPU傳送一箇中斷訊號來通知CPU。基本思想是中斷會發訊號到CPU晶片的一個外部引腳上。這會導致CPU暫停它當前正在做的工作,跳轉到一個作業系統例程。這個程式會記錄下I/O已經完成,然後將控制返回到CPU被中斷地地方。