MIPS指令學習二


1、MIPS尋址方式

  MIPS架構的尋址模式有寄存器尋址、立即數尋址、寄存器相對尋址和PC相對尋址4種,其中寄存器相對尋址、PC相對尋址介紹如下:

1.1、寄存器相對尋址

  這種尋址模式主要被加載/存儲指令使用,其對一個16位的立即數進行符號擴展,然后與指定通用寄存器的值相加,從而得到有效地址。

  通用寄存器GRP   +   16位立即數做符號擴展      =       有效地址

1.2、PC相對尋址

  這種尋址模式主要被轉移指令使用。在轉移指令中有一個16位的立即數,將其左移2位並進行符號擴展,然后與程序計數器PC的值相加,可得到有效地址。

  程序計數器PC     +      16位立即數左移2位並做符號擴展     =     有效地址

 

2、MIPS指令集

2.1、MIPS指令特點

  • MIPS固定4字節指令長度。
  • 內存中的數據訪問(load/store)必須嚴格對齊(至少4字節對齊)。
  • 跳轉指令只有26位目標地址,加上2位對齊位,可尋址28位尋址空間,即256MB。
  • 條件分支指令只有16位跳轉地址,加上2位對齊位,共18位尋址空間,即256KB。
  • MIPS默認不把子函數的返回地址(就是調用函數的受害指令地址)存放到棧中,而是存放到$31($ra)寄存器中,這對那些葉子函數(在函數中不再調用其他函數的函數)有利。如果遇到嵌套函數,有其他機制處理。
  • 流水線效應。MIPS采用了高度的流水線,其中一個最重要的效應就是分支延遲效應。在分支跳轉語句后面的那條語句叫做分支延遲槽。實際上,在程序執行到分支語句時,當它剛把要跳轉到的地址填充好(填充到代碼計數器里),還沒有完成本條指令時,分支語句后面的那個指令就已經執行了,其原因就是流水線效應 ---- 幾條指令同時執行,只是處於不同的階段。

  流水線效應:

  mov $a0, $s2

  jalr strrchr

  move $a0, $s0

  在執行第2行跳轉分支時,第3行的move指令已經執行完了。因此,在上面指令序列中,strrchr函數的參數來自第3行的$s0,而不是第1行的$s2。

  從流水線效應中可以看出,是否正確理解MIPS指令的這些特點會直接影響我們對MIPS程序逆向分析的結果,因此,我們需要熟悉把握這些特點。

 

2.2、指令格式

  所有MIPS指令的長度相同,都是32位。為了讓指令的格式剛好合適,設計者做了折中:將所有指令定長,但是不同的指令有不同的格式。在MIPS架構中,指令的最高6位均為Opcode碼,剩下的26位可以將指令分為3種類型,分別為R型、I型和J型。

  • R型指令用連續3個5位二進制碼表示3個寄存器的地址,然后用1個5位二進制碼表示移位的位數(如果未使用移位操作,則全為0),最后是6位的Function碼(它與Opcode碼共同決定R型指令的具體操作方式)。
  • I型指令則用連續2個5位二進制碼表示2個寄存器的地址,然后是由1個16位二進制碼表示1個立即數二進制碼。
  • J型指令用26位二進制碼表示跳轉目標的指令地址(實際的指令地址應為32位,其中最低2位為“00”,最高4位由PC當前地址決定)。
類型 格式
R Opcode(6) Rs(5) Rt(5) Rd(5) Shamt(5) Funct(6)
I Opcode(6) Rs(5) Rt(5) Immediate(16)
J Opcode(6) Address(26)
  • Opcode: 指令基本操作,稱為操作碼。
  • Rs: 第一個源操作數寄存器。
  • Rt: 第二個源操作數寄存器。
  • Rd: 存放操作結果的目的操作數。
  • Shamt: 位移量。
  • Funct: 函數,這個字段選擇Opcode操作某個特定變體。

3、匯編常用的指令

  注意:$Rd表示目的寄存器, $Rs表示源寄存器,$Rt表示作為中間緩存的寄存器,"imm"表示立即數,“MEM[]“表示RAM中的一段內存,“offset"表示偏移量。

3.1、LOAD/STORE指令

  LOAD/STORE指令有14條,分別是lb、lbu、lh、lhu、ll、lw、lwl、lwr、sb、sc、sh、sw、swl和swr。

  以"l"開頭的都是加載指令,以"s"開頭的都是存儲指令,這些指令用於從存儲器中讀取數據,或者將數據保存在存儲器中。

3.1.1、LA(Load Address) 指令用於將一個地址或標簽存入一個寄存器。

語法 實例 備注
la $Rd, Label la $t0, val_1 復制val_1表示的地址到$t0寄存器中,其中val_1是一個Label

3.1.2、LI(Load Immediate)指令用於將一個立即數存入一個通用寄存器。

語法 實例 備注
lw $Rt, offset($Rs) lw $s0, 0($sp) "$s0 = MEM[$sp+0]",相當於取堆棧地址偏移0內存word長度的值到$s0中

3.1.3、LW(Load Word) 指令用於從一個指定的地址加載一個word類型的值到一個寄存器中。

語法 實例 備注
lw $Rt, offset($Rs) lw $s0, 0($sp) "$s0=MEM[$sp+0];",相當於取堆棧地址偏移0內存word長度的值到$s0中

3.1.4、SW(Store Word)用於將源寄存器中的值存入指定的地址。

語法 實例 備注
sw $Rt, offset($Rs) sw $a0,0($sp) "MEM[$sp+0]=$a0;",相當於將$a0寄存器中一個word大小的值存入堆棧,且$sp自動堆棧

3.1.5、MOVE指令用於寄存器之間值的傳遞。

語法 實例 備注
move $Rt, $Rs move $t5, $t1 $t5=$t1;

 

3.2、算術運算指令

  MIPS匯編指令的算術運算特點如下:

  • 算術運算指令的所有操作數都是寄存器,不能直接使用RAM地址或間接尋址。
  • 操作數大小都為word(4 Byte)。
  • 算術運算指令有21條,分別為add、addi、sub、subu、clo、clz、slt、slti、sltiu、sltu、mul、mult、madd、maddu、msub、msubu、div和divu,實現了加、減、比較、乘、乘累加、除等運算。
指令格式與實例 注釋
add $t0,$t1,$t2 "$t0=$t1+$t2;",帶符號數相加
sub $t0,$t1,$t2 "$t0=$t2 - $t2;", 帶符號數相減
addi $t0,$t1,5 $t0 = $t1 + 5;
addu $t0,$t1,$t2 "$t0 = $t1 + $t2;",無符號數相加
subu $t0, $t1, $t2 "$t0 = $t2 - $t2;",無符號數相減
mult $t3, $t4 "$t3 * $t4", 把64 Bits的積存儲到"Lo,Hi"中,即"(Hi,Lo)=$t3 * $t4;"
div $t5, $t6 "$LO=$t5/$t6", $LO為商的整數部分;"$HI=$t5 mod $t6", $HI為余數
mfhi $t0 $t0 = $HI
mflo $t1 $t1 = $LO

 

  

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM