MIPS體系架構

MIPS體系結構首先是一種RISC架構
1 MIPS32架構中有32個通用寄存器,其中$0(無論你怎麼設置,這個寄存器中保存的數據都是0)和$31(保存函數調用jal的返回地址)有着特殊的用途,其它的寄存器可作爲通用寄存器用於任何一條指令中。
雖然硬件沒有強制性的指定寄存器使用規則,在實際使用中,這些寄存器的用法都遵循一系列約定。這些約定與硬件確實無關,但如果你想使用別人的代碼,編譯器 和操作系統,你最好是遵循這些約定。
寄存器編號 助記符 用法
0 zero 永遠返回值爲0
1 at 用做彙編器的暫時變量
2-3 v0, v1 子函數調用返回結果
4-7 a0-a3 子函數調用的參數
8-15 t0-t7
24-25 t8-t9 暫時變量,子函數使用時不需要保存與恢復
16-25 s0-s7 子函數寄存器變量。子函數必須保存和恢復使用過的變量在函數 返回之前,從而調用函數知道這些寄存器的值沒有變化。
26,27 k0,k1 通常被中斷或異常處理程序使用作爲保存一些系統參數
28 gp 全局指針。一些運行系統維護這個指針來更方便的存取“static“和”extern" 變量。
29 sp 堆棧指針
30 s8/fp 第9個寄存器變量。子函數可以用來做楨指針
31 ra 子函數的返回地
2 MIPS32中如果有FPA(浮點協處理器),將會有32個浮點寄存器,按彙編語言的約定爲$f0~$f31,MIPS32中只能實用偶數號的浮點寄存器,奇數號的用途是:在做雙精度的浮點運算時,存放該奇數號之前的偶數號浮點寄存器的剩餘無法放下的32位。比如在做雙精度的浮點運算時,$1存放$0的剩餘的部分,所以在MIPS32中可以通過加載偶數號的浮點寄存器而把64位的雙精度數據加載到兩個浮點寄存器中,每個寄存器存放32位。
比如:
l.d $02, 24(t1)
被擴充爲兩個連續的寄存器加載:
lwc1 $f0, 24(t1)
lwc1 $f1, 28(t1)
3 MIPS架構中沒有X86中的PC(程序計數)寄存器,它的程序計數器不是一個寄存器。因爲在MIPS這樣具有流水線結構的CPU中,程序計數器在同一時刻可以有多個給定的值,如
jal指令的返回地址跟隨其後的第二條指令。
...
jal printf
move $4, $6
xxx # return here after call
MIPS32中也沒有條件碼,比如在X86中常見的狀態寄存器中的Z、C標誌位在MIPS32中是沒有的,但是MIPS32中是有狀態寄存器
4 MIPS32中不同於其它的RISC架構的地方是其有整數乘法部件,這個部件使用兩個特殊的寄存器HI、LO,並且提供相應的指令 mfhi/mthi,mthi/mtlo來實現整數乘法結果--hi/lo寄存器與通用寄存器之間的數據交換
5 數據加載與存儲
MIPS CPU可以在一個單一操作中存儲1到8個字節。文檔中和用來組成指令助記符的 命名約定如下:
C名字 MIPS名字 大小(字節) 彙編助記符
long long dword 8 "d"代表ld
int/long word 4 "w"代表lw
short halfword 2 "h"代表lh
char byte 1 "b"代表lb
5.1數據加載
包括這樣幾條記載指令LB/LBU、LH/LHU、LW
byte和short的加載有兩種方式。帶符號擴展的lb和lh指令將數據值存放在32位寄存器的低位中,剩下的高位用符號位的值來擴充(位7如果是一個byte,位15如果是一 個short)。這樣就正確地將一個帶符號整數放入一個32位的帶符號的寄存器中。
不帶符號指令lbu和lhu用0來擴充數據,將數據存放縱32位寄存器的低位中,並將高位用零來填充。
例如,如果一個byte字節寬度的存儲器地址爲t1,其值爲0xFE(-2或254如果是非符
號數),那麼將會在t2中放入0xFFFFFFFE(-2作爲一個符號數)。t3的值會是0x000000FE(254作
爲一個非符號數)
lb t2, 0(t1)
lbu t3, 0(t1)
5.2數據存儲
包括這樣幾條指令SB、SH、SW
由於加載就是把寄存器中的數據加載到內存中,所以不存在位擴展的問題。
6 CP0 (協處理器0)--MIPS處理器控制
用於控制和設置MIPS CPU,裏面包含了一些寄存器,同過對這些寄存器的不同的位的操作可以實現對處理器的設置
CP0類似於X 86只能有內核 (高優先級權限)訪問的一些處理器資源
而前面提到的通用寄存器GPR和FPR則可以有由所有的優先級權限訪問
CP0提供了中斷異常處理、內存管理(包括CACHE、TLB)、外設管理等途徑(而這些只能由高優先級的內核才能訪問到)。
6.1常見的MIPS CPU控制寄存器包括:
SR( 狀態寄存器) 12
Config (CPU參數設置寄存器)-16
EPC (例外程序寄存器)13、 CAUSE(導致中斷和異常的原因寄存器) 14、BadVaddr(地址錯誤時存放地址的寄存器)8
Index-0、Random-1、EntryLo0-2、EntryLo1-3、EntryHi-10、PageMask
Count-9、Compare-11共同組成了高精度的時鐘
6.2CP0寄存器的訪問指令
mtc0 ts, #把通用寄存器 ts中的數據送到協處理器0中的寄存器nn
mfc0 ts, #把送到協處理器0中寄存器 nn 的值送到通用寄存器ts
dmtc0 ts, #把通用寄存器 ts中的數據送到協處理器0中的寄存器nn
dmfc0 ts, #把送到協處理器0中寄存器 nn 的值送到通用寄存器ts
6.3起作用的寄存器及其作用時機
加電後:你需要設置SR和Config寄存器,以確保CPU進入正確的引導狀態,並且SR寄存器還設置了中斷碼。以決定系統響應哪些中斷。
進入任何異常:處理任何例外都會調用一個“通用異常處理程序”。MIPS體系並沒有爲進入異常作任何的寄存器保存,也沒有關於堆棧方面的任何支持,進入異常時唯一保存的就是異常返回地址保存在EPC中。所以這些都需要操作系統的軟件實現。操作系統可以使用K0或者K1寄存器作爲堆棧指針,指向某個位置,並且在需要保存的寄存器保存到這個棧上。然後通過Cause寄存器找到發生異常的原因,這樣才能跳轉到對應的中斷處理程序中。
從異常返回:從異常返回到EPC制定的地址之前要把CPU的狀態回覆到異常之前,好象什麼事情都沒有發生一樣。在R3000中使用rfe指令作這樣的事情,但是着條指令僅僅恢復了一些寄存器中的內容,但是並沒有轉移控制指令,你需要把EPC內容保存到一個通用寄存器中,然後調用jr指令返回到EPC指向的地址處,
7 MIPS的存儲管理模型
MIPS32中的存儲器模型被劃分爲四個大塊,其中:
0x0000,0000~0x7fff,ffff(0~2G-1) USEG
must be mapped (set page table and TLB)and set cache before use
0x8000,0000~0x9fff,ffff(2G~2.5G-1) KSEG0
directly mapped(no need to set page table and TLB) but need to set cache before use
0xa000,0000~0xbfff,ffff(2.5G~3G-1) KSEG1
directly mapped(no need to set page table and TLB) and never use cache
0xc000,0000~0xffff,ffff(3G~4G-1) KSEG2
muse be mapped(set page table and TLB) and set cache before use
這樣的存儲器管理模型和X86差距比較大,X86有一個實模式,內核在啓動保護模式之前,運行在實模式之下,直到設定了保護模式之後才能運行在保護模式下。在MIPS32中沒有保護模式那麼系統是如何啓動的呢?
MIPS32中的系統啓動向量位於KSEG1中0xbf10,0000,由於KSEG1是directly mapped的,所以直接對應了物理地址0x1fc0,0000,你可以在內核中一直使用0xa000,0000~0xbfff,ffff之間的虛擬地址來訪問物理地址0~512M-1,在設置了KSEG0的cache之後,也可一使用0x8000,0000~0x9fff,ffff之間的虛擬地址來訪問0~512M-1之間的物理地址。對於512M以上的物理地址只能由KSEG2和USEG通過頁表訪問。
8 MIPS32中的狀態寄存器SR
狀態寄存器來設置處理器的一些功能集合,包括設置
設置協處理器0~3的可用性的位CU0~CU3(28~31)
復位向量BEV
中斷屏蔽位8~15
KUc、IEc0~1,基本的CPU保護單位
KUc爲1時表示運行在內核態,爲0時運行在用戶模式。在內核態下,可以訪問所有的地址空間和協處理器0,運行在用戶態下值只能訪問0x0000,0000~0x7fff,ffff之間的地址空間。
KUp、IEp2~3
當異常發生時,硬件把KUc、IEc的值保存到KUp、IEp中,並且將KUc、IEc設置爲[1,0]--內核態、關中斷。異常返回時 rfe指令可以把KUp、IEp的內容複製到KUc、IEc中
KUo、IEo
當異常發生時,硬件把KUp、IEp的值保存到KUo、IEo中;返回時把KUo、IEo的內容複製到KUp、IEp中。
上面三對KU/IE位構成了深度2的棧,異常發生時,硬件自動壓棧,rfe指令從異常返回時,從棧中恢復數值
還有一些其它的功能和狀態位,可以參考相應的文檔
9 MIPS32中的Cause寄存器
BD位:EPC中正常情況下存放了發生異常的指令,但是當着條指令存放在調轉指令的延遲槽中時,那麼EPC中存放的是這個跳轉指令,否則這條跳轉指令將得不到執行。
IP位:告訴用戶來臨的中斷
ExcCode:這是一個5位的代碼,告訴你哪一條異常發生了,可以根據這個從通用異常處理程序跳裝到特定異常處理程序中。
10 MIPS32的C語言中參數傳遞和返回值的約定
caller至少使用16bytes 堆棧空間存放參數,然後把這16 bytes存放到通用寄存器a0~a3中, called subroutine 直接使用寄存器中的參數,同時caller 堆棧中的16bytes的數據可以不去理會了。
需要理解的是帶有浮點參數和結構體的參數傳遞,對於帶有浮點參數的傳遞需要看第一個參數是否是浮點,如果是浮點則將參數放到 $f12和$f14這兩個浮點寄存器中,如果第一個參數不是浮點數,則不用浮點寄存器存放參數。對於結構體的參數傳遞和x86類似
對於整數和指針類型的

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章