MIPS指令簡介
MIPS指令的基本格式分為三種:R型、I型和J型。R型(Register)指的是寄存器型,I型(Immediate)指的是立即數型,J型(Jump)指的是無條件轉移型。
指令格式位R型的運算指令
R型指令格式包含6個域,最高位的opcode域,是6個比特,最低位的funct域也是6個比特, 中間rs、rt、rd、shamt均為5個比特。
opcode用於指定指令的類型,對於所有R型指令,該域的值均為0,但這並不是說明R型指令只有一種,它還需要用funct 域來更為精確的指定指令的類型,所以說對於R型指令,實際上一共有12個比特操作碼。
rs Source Register 通常用於指定第一個源操作數所在的寄存器編號
rt Target Register 通常用於指定第二個源操作數所在的寄存器編號
rd Destination Register 通常用於指定目的操作數(保存運算結果)的寄存器編號
5-bit的域可表示0~31,對應32個通用寄存器
shamt shift amount 用於指定移位指令進行移位操作的位數,對於非移位指令,該域設為0。
opcode | rs | rt | rd | shamt | funct |
6-bit | 5-bit | 5-bit | 5-bit | 5-bit | 6-bit |
R型指令
I型指令的格式
R型指令只有一個5-bit域(移位域)表示立即數,范圍為0~31
opcode | rs | rt | immediate |
6-bit | 5-bit | 5-bit | 16-bit |
I型指令
opcode用於指定指令的操作類型(但沒有funct 域)
rs Source Register 通常用於指定第一個源操作數所在的寄存器編號
rt Target Register 指定用於目的操作數(保存運算結果)的寄存器編號,對於某些指令指定第二個源操作數所在的寄存器編號
immediate 16-bit的立即數,可以表示2^16個不同數值
對於訪存指令(需要一個寄存器,加上一個立即數來指示一個內存單元,這個立即數就是訪存地址的偏移量),如 lw rt, imm (rs),通常可以滿足訪存地址偏移量的需求(-32768~+32767)
對於運算指令,如addi rt , rs , imm 無法滿足全部需求,但大多數時候可以滿足要求。這一點體現出X86這樣的CISC指令系統的優勢,對於X86指令來說,如果想使用更大寬度的立即數,它可以很容易的擴展,因為它的指令沒有限制長度。但是MIPS指令就不行,它的指令總長度就是32位的,再加上各個寄存器位域的使用,所以I型指令最多只能使用十六位的立即數。
分支指令
Branch :改變控制流,相當於X86中的轉移指令
Conditional Branch
條件分支:根據比較的結果改變控制流
兩條指令: branch if equal (beq); branch if not equal (bne)
Unconditional Branch
非條件分支:無條件地改變控制流
一條指令:jump ( j )
條件分支指令(I型)
條件分支
beq rs , rt , imm # opcode=4
bne rs , rt , imm # opcode=5
格式:beq reg1,reg2,L1 (beq指令,它共有三個操作數,前兩個是寄存器操作數,第三個操作數是存儲器地址,也就是一個立即數,CPU會判斷第一個寄存器當中的數和第二個寄存器當中的數是否相等。如果相等就跳轉到L1所指向的寄存器單元取出下一條指令,否則順序執行beq之后的那條指令)
if(value in reg1)==(value in reg2)
goto L1
這里和X86的條件轉移指令有很大的不同,MIPS沒有標志寄存器,它就在一條指令當中即進行了比較,又完成了轉移,MIPS全稱就是為了減少指令流水線的互鎖,也就是盡量避免不同指令之間相互的影響。而標志位這件事,就是前一條指令運行的結果,可能會對后面的某條指令產生影響,這是MIPS指令設計時要盡量避免的,所以beq指令也很好的體現了MIPS的這一設計理念。
條件分支指令的目標地址范圍,在MIPS中,指向下一條指令地址的寄存器為PC,類似於X86中的IP寄存器,這個寄存器,是指向32位地址的,如果以當前PC寄存器為基准,16位位移量可以表示出當前指令前后2^15字節這么一個范圍,MIPS指令長度固定為32個bit,因此每條指令的位置,一定會在4個字節對齊的地方,這樣的地址最低兩位肯定位0,所以我們實際上可以用十六位的位移量去指示每四個字節為一個單位的地址,這樣就可以把目標地址的范圍擴大四倍,可以達到前后128KB。
目標地址計算:
分支條件不成立,PC=PC+4= next instruction
分支條件成立,PC=(PC+4)+(immediate*4)
非條件分支指令(J型)
opcode | address |
6-bit | 26-bit |
J型指令
目標地址計算方法:New PC={(PC+4)[ 31..28 ] , address , 00 } (下一條指令的地址的計算方法是當前的PC加四之后,取最高的四位,再加上J型指令編碼中的26位,然后在末尾添加兩個零)
J型指令的目標地址范圍:前后2^28字節(前后256MB)
非條件分支指令(R型)
如何到達更遠的目標地址
可以兩次調用J指令,第一條J指令盡可能調到最遠的地方,然后在那個目標地址再放一條J指令。或者使用 jr 指令,jr 指令有一個寄存器操作數,可以把要轉移的目標地址放到寄存器當中,這樣可以使用32位的目標地址,就用原來的 r 型指令就可以很好的實現,只用占用其中的一個寄存器位域, 然后新增一種function的編碼就可以了。