一個完整的指令集結構包括
Instuction Fetch |
Instuction Decode |
Operand Fetch |
Excute |
Result Store |
Next Instruction |
我們必須解決的問題包括:
- 指令的編碼方式(即如何編碼)
- 操作數和操作結構的存放位置
- 存放位置
- 多少個現實操作數
- 存儲器操作數如何定位
- 那些操作數可以或不可以放到存儲器中
- 數據的類型和大小
- 支持哪些操作
- 下一條指令的地址
- jumps,conditions,branches
- fetch-decode-execute is implicit
- 有關ISA的若干問題
- 分類
-
stack 0 address ADD tos<---tos+next Accumulator 1 address ADD A acc<---acc+mem[A] 1+x address ADDX A acc<---acc+mem[A+x] Register-memory 2 address ADD A B EA[A]<---EA[A] 3 address add A B C EA[A]<---EA[B]+EA[C] Load-Store 3 address add A B C A<---B+C load A B A<---mem[B] - 通用寄存器型(R-M R-R)占主導地位
- 寄存器比存儲器更快
- 對便一起來說寄存器更容易使用
- 尾端問題
-
- little endian,big endian,在一個字內部的字節順序問題,例如在地址xxx00指定了一個字(int),存儲器中從xxx00連續存放ffff0000,有兩種表示方式:
- 小端方式:xxx00位置是字的最低字節,數值為0000ffff。x86,dec vax,windows NT
- 大端方式:xxx00位置是字的最高字節,數值為ffff0000。IBM 360/370,Motorola,MIPS
- little endian,big endian,在一個字內部的字節順序問題,例如在地址xxx00指定了一個字(int),存儲器中從xxx00連續存放ffff0000,有兩種表示方式:
-
- 對齊問題
- 對一個s字節的對象訪問,地址為A,如果A mod s ==0,則是邊界對齊
- 這是由於存儲器本身的讀寫要求的。沒有對其的對象可能會導致存儲器兩次讀寫。
- 基准測試結果:
- 偏移尋址、立即數尋址、寄存器尋址方式,其使用頻度為75%~99%
- 偏移字段大小為12~16bits,可滿足75%~99%的需求
- 立即數字段大小為8~16bits,可滿足50%~80%的需求
- 分類
操作數類型和操作數表示
類型:是面向應用、面向軟件系統處理的各種操作數據類型。整型、浮點型、字符、字符串、向量類型;類型由操作碼確定。
表示:操作數在機器中的表示,硬件結構能夠識別,指令系統可以直接使用的表示格式。整型(原碼、補碼、反碼),浮點(IEE 754標准),十進制(BCD碼,二進制十進制表示)
- ISA研究的問題
- ISA的分類
- 操作數部分
- 理解存儲器地址(尾端+對齊問題)
- 尋址方式
- 操作數的類型、表示和大小問題
- 操作碼部分
- 支持哪些類型的操作
- 指令格式
- 研究的方法:基於統計的方法
- 結論:
- 常用的尋址方式:立即數、偏移尋址、寄存器尋址
- 偏移字段的大小:12~16bits
- 立即數字段的大小8~16bits
- 操作數大小:單字、雙字的數據訪問頻率高;64字長更具一般性
- ISA的功能設計
- 任務:確定硬件支持哪些操作
- 方法:統計
- 類型:CICS和RISC
- 控制類指令
- 條件分支最常見
- 尋址方式:pc-relative和偏移地址至少8位;即動態的轉移地址方式
- CISC
- 強化指令功能,減少程序中指令條數
RISC計算機指令集結構的功能設計
- 特點:
- 大多數指令在單周期內完成
- 采用load、store結構
- 硬布線控制邏輯
- 減少指令和尋址方式種類
- 固定的指令格式
- 注重代碼的優化
- 面向寄存器結構
- 重視流水線的執行效率--》盡量減少斷流
- 重視優化編譯技術
- RISC為了使流水線高效執行
- 簡單而統一的指令譯碼
- 大部分指令可以單周期完成
- 只有load/store指令訪存
- 簡單尋址技術
- 采用load延遲技術
- 為了便於優化編譯產生優化代碼
- 三地址指令格式
- 較多適量的寄存器
- 對稱的指令格式
- RISC的關鍵技術
- 延遲轉移技術
- 指令取消技術
- 重疊寄存器窗口技術
- 處理器中設置多個寄存器堆,並划分多個窗口
- 每個過程使用其中相鄰的三個窗口和一個公共的窗口
- 一個與前一個過程公用;一個與下一個過程公用;一個作為局部寄存器
- 指令調整技術
- 硬件為主,固件為輔
- 頻率較高的指令:load,store,add,subtract,move register-register,and,shift,compare equal,compare not equal,branch,jump,call,return
- 控制類指令:conditional branch,jump,procedure calls,procedure returns
- 控制類指令的尋址方式:pc-relative
- 編譯時不知道轉移地址,程序執行時動態確定
- 轉移地址放到某一寄存器中
- 指令編碼方式
- 長度可變
- 長度固定
- 混合
MIPS尋址方式/指令格式(所有指令都是32bit)
- 寄存器直接尋址
- 立即數尋址
- 基址尋址
- pc相對尋址
- 寄存器間接尋址
現代編譯技術與計算機體系結構設計
- ISA設計需要了解的有掛compiler的問題
- 如何分配變量
- 高級語言分配數據的區域
- stack
- 用來分配局部變量;用來存儲活動記錄(call和return),工作堆棧指針訪問其中的內容
- global data area
- 用來分配被靜態說明的對象,如常亮和全局變量、其中數組和其他聚集類型的數據結構比例大。
- heap
- 分配動態對象,用指針訪問,通常不是標量。全局變量和堆變量因為存在別名問題而無法分配寄存器
- stack
- 高級語言分配數據的區域
- 如何尋址變量
- 需要多少寄存器
- 優化技術對指令使用頻率的影響
- 使用哪些控制結構
- 如何分配變量
- MIPS指令集結構
- MIPS的寄存器
- 32個64bit通用寄存器(GPRS)
- r0,r1,...,r31
- 整數寄存器
- r0 = 0
- 32個64bit浮點寄存器(FPRS)
- f0,f1,...,f31
- 用來存放32個單精度浮點數(32bit),也可以用來存放32個雙精度浮點數(64bit)
- 存放單精度數時,只用了FPR的一半;
- 一些特殊寄存器
- 可以與通用寄存器交換數據
- 浮點狀態寄存器保存浮點操作的結果
- 32個64bit通用寄存器(GPRS)
- MIPS的數據表示
- 整數
- 字節8bit ;半字16bit;字32bit;雙字64bit
- 浮點數 單精度(32bit),雙精度(64bit)
- 字節、半字、字被裝入64位寄存器時,零擴展或符號擴展。
- 整數
- 尋址方式
- 立即數尋址和偏移量尋址,其立即數、偏移量字段都是16bit
- 寄存器間接尋址是通過把0作為偏移量來實現的
- 16bit絕對尋址是通過把R0作為基址寄存器來實現
- mips的存儲器按字節尋址,地址為64bit
- 所有的存儲器訪問都是邊界對齊
- 指令格式
- 尋址方式編碼到操作碼中
- 所有指令都是32bit
- 操作碼占6bit
- 3中指令格式
- I類指令
,立即數字段為16bit,用於提供立即數和偏移量
-
load指令 訪存有效地址:Regs[rs]+immediate
從存儲器取來的數據放入寄存器rt中 store指令 訪存有效地址:Regs[rs]+immediate 從存儲器取來的數據放入寄存器rt中 立即數指令 Regs[rt]<---Regs[rs] op immediate 分支指令 目標轉移地址:Regs[rs]+immediate rt無用 寄存器跳轉、寄存器跳轉並連接 轉移目標地址為Regs[rs]
- R類指令
- 包括ALU指令,專用寄存器讀/寫指令,move指令
- ALU指令 Regs[rd]<---Regs[rs] func Regs[rt],func為具體的運算操作編碼
- J類指令
- 包括跳轉指令、跳轉並連接指令、自陷指令、異常返回指令;
- 指令字的低26位是偏移量,左移兩位,與pc值相加,形成跳轉的地址。
- I類指令
- 指令的分類(load/store,ALU操作,分支與跳轉,浮點操作)
- 符號的意義
- x<---ny:從y傳送n位到x
- x,y<---z:把z傳送到x和y
- 下標:表示字段中具體的位;對於指令和數字,按從最高位到最低位(左--》右)順序依次編號,最高位為第0位,次高位為第1位。
- 下表可以是數字或者一個范圍;Regs[R4]0,即R4的符號位;Regs[R4]56...63的最低位
- Mem:表示主存,按字節尋址
- 上標:用於表示對字段進行復制的次數;032一個32位全0的字段
- 符號##,用於連個字段的拼接,並且可以出現在數據傳送的任何一邊。eg,R8、R10為64位的寄存器,則Regs[R8]32..63<---32(Mem[Regs[R6]]0)24##Mem[Regs[R6]];表示的是,以R6的內容作為地址訪問內存,得到的字節按符號位擴展的32位后存入R8的低32位,R8的高32位(即Regs[R8]0..31)不變。
- x<---ny:從y傳送n位到x
-
LD R2,20(R3) 裝入雙字 Regs[R2]<---64(Mem[20+Regs[R3]]) LW R2,40(R3) 裝入字 Regs[R2]<---64(Mem[40+Regs[R3]]0)32 ## Mem[40+Regs[R3]] LB R2,30(R3) 裝入字節 Regs[R2]<---64(Mem[30+Regs[R3]]0)56 ## Mem[40+Regs[R3]] LBU R2,40(R3) 裝入無符號字節 Regs[R2]<---64056 ## Mem[40+Regs[R3]] LH R2,30(R3) 裝入半字 Regs[R2]<---64(Mem[30+Regs[R3]]0)48 ## Mem[30+Regs[R3]]##Mem[31+Regs[R3]] L.S F2,60(R4) 裝入半字 Regs[F2]<---64Mem[60+Regs[R4]] ## 032 L.D F2,40(R3) 裝入雙精度浮點數 Regs[F2]<---64Mem[40+Regs[R3]] SD R4,300(R5) 保存雙字 Mem[300+Regs[R5]]<---64Regs[R4] SW R4,300(R5) 保存字 Mem[300+Regs[R5]]<---32Regs[R4] S.S F2,40(R2) 保存單精度浮點數 Mem[40+Regs[R2]]<---32Regs[F2]0..31 SH R5,502(R4) 保存半字 Mem[502+Regs[R4]]<---16Regs[R5]48..63 -
- ALU指令
-
DADDU R1,R2,R3 無符號加 DADDIU R4,R5,R6 加無符號立即數 LUI R1,#4 把一個立即數裝入到一個字的高16位 Regs[R1]<---032 ## 4 ## 016 DSLL R1,R2,#5 邏輯左移 Regs[R1]<---Regs[R2]<<5 DSLT R1,R2,R3 置小於 if(Regs[R2]<Regs[R3]) then Regs[R1]<---1 else Regs[R1]<---0
- 控制類指令
-
J name 跳轉 PC36..63<--- name<<2 JAL name 跳轉並連接 Regs[R31]<-- PC+4;PC36..63<---name<<2;((PC+4)-227)<=neme<((PC+4)+227) JALR R3 寄存器跳轉並連接 Regs[R31]<--- PC+4;PC<--Regs[R3] JR R5 寄存器跳轉 PC<-- Regs[R5] BEQZ R4,name 等於零時分支 if(Regs[R4]==0) then PC<-- name;((PC+4)-217)<=name<((PC+4)+217) BNE R3,R4,name 不相等時分支 ((PC+4)-217)<= name < ((PC+4)+217) MOVZ R1,R2,R3 等於零時移動 if(Regs[R3]==0) then Regs[R1]<--Regs[R2] - 跳轉指令(根據目標指令確定目標指令的方式不同以及是否跳轉時連接,可以將跳轉指令分為4類)
- 目標地址的確定方式:把指令中的26位偏移量左移2位后,替換pc中的低28位;由指令中指定的一個寄存器來給出目標轉移地址
- 跳轉的兩種類型:簡單跳轉(把目標地址送入程序計數器);跳轉並連接,將目標指令送入程序計數器,把返回地址(下一條)放入寄存器R31
- 分支指令(跳轉轉移)
- 分支指令指令的目標地址,由16位帶符號偏移量左移兩位后和pc相加決定。
- 浮點條件分支指令:通過測試浮點狀態寄存器來決定是否進行分支。
- MIPS的寄存器