第四章 處理器體系結構
第一節 Y86指令集體系結構
一、程式員可見的狀态:
每條指令都會讀取或修改處理器狀态的某些部分,稱為程式員可見狀态。
1、8個程式寄存器:%eax,%ecx,%edx,%ebx,%esi,%edi,%esp和%ebp。
2、條件碼:ZF(零)、SF(符号)、OF(有符号溢出)
3、程式計數器(PC):存放目前正在執行的指令的位址
4、存儲器:很大的位元組數組,儲存着程式和資料。Y86系統用虛拟位址來引用存儲器的位置,硬體和作業系統軟體聯合起來将虛拟位址翻譯成實際或實體位址。
5、狀态碼(stat):表明程式執行的總體狀态。(異常處理)
二、Y86指令

1、movl指令
IA32 movl指令:irmovl,rrmovl,mrmovl,rmmovl
(1)源操作數:i-立即數;r-寄存器;m-存儲器
(2)目的操作數:r-寄存器;m-存儲器
(3)指令附加的寄存器訓示符位元組依次是資料源(如果是立即數,把這一位設定成0xf)、目的寄存器/基址寄存器。 (4)有些指令需要附加四位元組的常數字,采用小端法(倒序)編碼
2、四個整數操作指令
addl加
subl減
andl與
xorl異或
三個條件碼:
ZF-零
SF-符号
OF-溢出
3、七個跳轉指令——分支控制:
jmp 直接跳轉
jle(SF^OF)|ZF 有符号數≤
jl SF^OF 有符号<
je ZF 相等/零
jne ~ZF 不相等/非零
jge ~(SF^OF) 有符号≥
jg ~(SF^OF)&~ZF 有符号>
根據分支指令的類型和條件碼的設定來選擇分支。
4、六個條件傳送指令:
cmovle
cmovl
cmove
cmovne
cmovg
與寄存器-寄存器傳送指令rrmovl一樣,但隻有當條件碼滿足所需要的限制時才會更新目的寄存器的值。
5、call和ret:
call:傳回位址入棧,然後跳到目的位址;
ret指令從這樣的過程調用中傳回。
6、pushl和popl:
入棧和出棧
7、halt:
停止指令的執行
三、指令編碼
1、指令的位元組級編碼。每條指令需要1-6個位元組不等。每條指令的第一個位元組表明指令的類型。
該位元組分為兩個部分,每部分4位:高4位是代碼部分,低4位是功能部分。功能值隻有在一組相關指令共用一個代碼時才有用。
2、整數操作:代碼部分均為6,功能部分區分addl,subl,andl,xorl
分支指令:代碼部分均為7
傳送指令:代碼部分均為2
3、8個程式寄存器當中,每個都有相應的0~7的寄存器辨別符。
4、程式寄存器存在CPU中的一個寄存器檔案中,這個檔案就是一個小的、以寄存器ID作為位址的随機通路存儲器。
5、有的指令隻有一個位元組,而有的需要操作數的指令編碼更長一點,就可能有附加的寄存器訓示符位元組,指定一個或兩個寄存器,這些寄存器字段為rA,rB
6、附加4位元組的常數字:這個字作為irmovl的立即數資料,rmmovl和mrmovl的位址訓示符的偏移量,以及分支指令和調用指令的目的位址。
四、Y86異常
1、狀态碼Stat可能取值
AOK 正常操作
HLT 處理器執行一條halt指令(指令停止)
ADR 遇到非法位址
INS 遇到非法指令
2、異常處理
Y86——處理器停止運作指令。
五、Y86程式
1、Y86和IA32的差別
1.需要多條指令來執行一條IA32指令所完成的功能
2.以“.”開頭的詞是編輯器指令
3.指令 .pos0告訴編輯器應該從位址0處開始産生代碼,這個位址是所有Y86程式的起點
4.聲明标号Steak,并用一個.pos指令指明位址0x100
第二節 邏輯設計和硬體控制語言HCL
電子電路中,用1.0V左右的高電壓表示邏輯1,用0.0V左右的低電壓表示邏輯0。
一、邏輯門
AND Y=a&&b
OR Y=a||b
NOT Y=!a
二、組合電路和HCL布爾表達式
很多邏輯門組合成一個網,建構計算塊。建構這些網有兩條限制。
1、兩個或多個邏輯門的輸出不能連在一起,否則可能會使線上的信号沖突,導緻一個不合法的電壓或電路故障
2、這個網必須是無環的
三、字級的組合電路和HCL整數表達式
所有字級的信号都聲明為int,并不指定字的大小
多路複用函數是用情況表達式來描述的,格式如下:
[
select_1 : expr_1
select_2 : expr_2
……
select_k : expr_k
]
從邏輯上講,這些選擇表達式是順序求值的。
不同選擇表達式之間允許不互斥
四、集合關系
通用格式:
iexpr in {iexpr1,iexpr2,...,iexprk}
其中被測值iexpr和待比對的值iexpr1-iexprk均為整數表達式。
五、寄存器和時鐘
組合電路簡單的響應輸入信号,産生等于輸入的某個函數的輸出,并存在狀态在這個狀态上進行計時,如此産生了時序電路。
随機通路存儲器:存儲多個字,用位址來選擇應該讀寫哪個字。
時鐘寄存器:存儲單個位或字,時鐘信号控制寄存器加載輸入值。
硬體寄存器工作時,每當每個時鐘到達上升沿時,值才會從寄存器的輸入傳送到輸出。 寄存器檔案讀資料是一個位址為輸入,資料為輸出的組合邏輯塊,寫入字是由時鐘信号控制的。
第三節 Y86的順序實作
一、将處理組織成階段
1、取指:從存儲器讀取指令位元組,位址為程式計數器(PC)的值。指令訓示符位元組兩個四位部分,稱為icode(指令代碼)和ifun(指令功能)。vaIP(下一條指令的位址)=PC+已取出指令的長度。
2、譯碼:從寄存器檔案讀入最多兩個操作數,得到valA和/或valB。
3、執行:算數邏輯單元(ALU)根據ifun的值執行指令指明的操作,計算存儲器引用的有效位址,或者增加或減少棧指針。得到的值稱為valE。也可根據條件碼執行跳轉。
4、訪存:将資料寫入存儲器,或者從存儲器讀出資料。讀出的值為valM。
5、寫回:最多可以寫兩個結果到寄存器檔案。
6、更新PC:将PC設定成下一條指令的位址。
二、SEQ硬體結構
1、取指:将程式計數器寄存器作為位址,指令存儲器讀取指令的位元組。PC增加器計算valP,即增加了的程式計數器。
2、譯碼:寄存器檔案有兩個讀端口A和B,從這兩個端口同時讀寄存器的值valA和valB。
3、執行:根據指令類型将算數/邏輯單元(ALU)用于不同的目的。條件碼寄存器有三個條件碼位,ALU負責計算條件碼的新值,當執行跳轉指令時會根據條件碼和跳轉類型來計算分支信号Cnd。
4、訪存:資料存儲器讀出或寫入一個存儲器字。指令和資料存儲器通路的是相同的存儲器位置,但用于不同的目的。
5、寫回:寄存器檔案有兩個寫端口,E用來寫ALU計算出來的值,M用來寫從資料存儲器中讀出來的值。
三、SEQ的時序
四個硬體單元:
1、程式計數器
2、條件碼寄存器
3、資料存儲器
4.寄存器檔案
它們通過一個時鐘信号來控制。
Y86指令集的計算原則: 處理器從來不需要為了完成一條指令的執行而去讀由該指令更新了的狀态
四、SEQ階段的實作
1、取指階段,包括指令儲存器硬體單元
2、譯碼和回寫階段
3、執行階段,包括算數/邏輯單元
4、訪存階段,讀或寫程式資料
5、更新PC階段
6、SEQ小結
五、實驗運作結果
(1)建構YIS環境:
cd ~/Code/shiyanlou_cs413
wget http://labfile.oss.aliyuncs.com/courses/413/sim.tar
tar -xvf sim.tar
cd sim
sudo apt-get install tk
sudo ln -s /usr/lib/x86_64-linux-gnu/libtk8.6.so /usr/lib/libtk.so
sudo ln -s /usr/lib/x86_64-linux-gnu/libtk8.6.so /usr/lib/libtk.so
make
(2)測試教材P239代碼asuml.ys,得到代碼:
| /* $begin code-yso */
| /* $begin code-ysa */
| # Execution begins at address 0
| # This version uses a leave instruction
0x000: | .pos 0
0x000: 30f400040000 | init: irmovl Stack, %esp # Set up Stack pointer
0x006: 30f500040000 | irmovl Stack, %ebp # Set up base pointer
0x00c: 7024000000 | jmp Main # Execute main program
|
| # Array of 4 elements
0x014: | .align 4
0x014: 0d000000 | array: .long 0xd
0x018: c0000000 | .long 0xc0
0x01c: 000b0000 | .long 0xb00
0x020: 00a00000 | .long 0xa000
|
0x024: 30f004000000 | Main: irmovl $4,%eax
0x02a: a00f | pushl %eax # Push 4
0x02c: 30f214000000 | irmovl array,%edx
0x032: a02f | pushl %edx # Push array
0x034: 803a000000 | call rSum # Sum(array, 4)
0x039: 00 | halt
|
| # int Sum(int *Start, int Count)
0x03a: a05f | rSum: pushl %ebp
0x03c: 2045 | rrmovl %esp,%ebp
0x03e: 30f014000000 | irmovl $20,%eax
0x044: 6104 | subl %eax,%esp
0x046: a03f | pushl %ebx
0x048: 503508000000 | mrmovl 8(%ebp),%ebx
0x04e: 50050c000000 | mrmovl 12(%ebp),%eax
0x054: 6200 | andl %eax,%eax
0x056: 718b000000 | jle L38
0x05b: 30f2f8ffffff | irmovl $-8,%edx
0x061: 6024 | addl %edx,%esp
0x063: 30f2ffffffff | irmovl $-1,%edx
0x069: 6020 | addl %edx,%eax
0x06b: a00f | pushl %eax
0x06d: 30f204000000 | irmovl $4,%edx
0x073: 2030 | rrmovl %ebx,%eax
0x075: 6020 | addl %edx,%eax
0x077: a00f | pushl %eax
0x079: 803a000000 | call rSum
0x07e: 502300000000 | mrmovl (%ebx),%edx
0x084: 6020 | addl %edx,%eax
0x086: 708d000000 | jmp L39
0x08b: 6300 | L38: xorl %eax,%eax
0x08d: 5035e8ffffff | L39: mrmovl -24(%ebp),%ebx
0x093: d0 | leave
0x094: 90 | ret
|
0x400: | .pos 0x400
0x400: | Stack: # The stack goes here
| /* $end code-ysa */
| /* $end code-yso */
六、遇到的問題
1、先是沒有找到Y86模拟器安裝入口
應該将sim得壓縮包解壓,最後成功連接配接Y86
七、參考來源
1、教材《深入了解計算機系統》
2、實驗樓實驗指導書《深入了解計算機系統》:https://www.shiyanlou.com/courses/413 實驗五
3、Y86 Tools:http://csapp.cs.cmu.edu/2e/students.html