計算機組成原理--MIPS指令的表示和邏輯操做

計算機組成原理--10.5

1.計算機中指令的表示

前言

指令在計算機內部是用高低電平表示的,而且看上去和數的表示是同樣的。實際上,指令的各個部分均可以當作數,將這些數拼在一塊兒就構成了指令。(實際上指令和數據的存儲確確實實是同樣的--都是二進制數)數組

在接下來的學習中須要用的部分的寄存器,因此在這裏先作簡單引入。less

寄存器$s0~$s7映射到寄存器16~23,寄存器$t0~$t7映射到寄存器8~15.(這裏s和t都只是標號,在以後的學習中咱們會知道,s表明保留寄存器,t表明臨時寄存器)ide

指令格式

指令的佈局形式叫作指令格式。佈局

MIPS指令佔32位,與數據字的位數相等。學習

數據字的定義:數據字,因爲計算機使用的信息既有指令又有數據,因此計算機字能夠表明指令,也能夠表明數據。若是某字表明要處理的數據,則稱爲 數據字;若是某字爲一條指令,則稱爲指令字-------百度百科測試

MIP字段

op rs rt rd shamt funct
6位 5位 5位 5位 5位 6位
操做碼 操做數寄存器1 操做數寄存器2 目的寄存器 位移量(以後介紹) 功能碼

這是一種三地址指令,rd存放的是操做的結果。spa

問題:若是有些指令須要常數的參與,例如取數操做那該怎麼作?設計

可能一開始想到的答案就是,把數放在rs,rt,rd段中,須要用常數的時候的時候,把他從去字段中取出。code

但實際上,這種操做方法會出現問題,當參與操做的常數>32(2^5)時就會出現超出範圍的問題。所以又但願全部指令的長度同樣,又但願可以有統一的指令格式,同時還要避免出現操做的常數過小的問題.......就出現了心得指令格式:blog

I型指令

前面所介紹的指令類型叫作R型指令,即寄存器型指令,I型指令爲用於當即數的指令

op rs rt constant or adress
6位 5位 5位 16位
操做碼 操做數寄存器1 操做數寄存器2 常數或者地址

例如:

1 lw $s0,32($s3)  #取字指令
2                         #$3存放在rs中,$0存放在rt中,32存放在address字段
3                         #此時rt的意義已經發生了變化
4                         #rt:指明接收取數結果的寄存器    

 

四種操做方式所對應的指令格式:

指令 格式 op rs rt rd shamt funct address
add R 0 reg reg reg 0 32(10) n.a.
sub R 0 reg reg reg 0 34(10) n.a.
addi(當即數) I 8(10) reg reg n.a. n.a. n.a. constant
lw I 35(10) reg reg n.a. n.a. n.a. address

(reg表明使用寄存器,address表明16位地址,n.a.表明不出現)(add和sub的op是相同的,區分他們的是funct)

經過觀察能夠發現,R型和I型的前三個字段長度相等,而且名稱也同樣;I型格式的第四個字段和R型後三個字段長度之和相等。R型和I型雖然功能不一樣可是卻構造很類似,而相關指令在二進制表示上的類似性能夠簡化硬件的設計。

 

補充:存儲程序:將指令和數據以相同的方式存儲,極大的簡化了計算機系統。

1)指令用數的形式表達

2)和數同樣程序存儲在存儲器中,而且能夠讀寫

2.邏輯操做

邏輯左移與邏輯右移

以前在R型指令格式的介紹中,有一部分沒有介紹--shamt字段(shift amount

shamt字段用來表示偏移量,常常用於邏輯左移(sll)和邏輯右移(srl)中。

邏輯左/右移:把一個字裏全部的位都向左/右移動,並在空出的地方補0

sll $t2,$s0,4 #reg $t2 = reg $s0 << 4 bits
op rs rt rd shamt funct
0 0 16 10 4 0

邏輯左移還有額外的好處,左移i位= 數 * 2^i

按位與(AND)和按位或(OR)

AND提供了一種將源操做數置零的方法。

1 假設$t1
2 0000 0000 0000 0000 0000 1101 1100 0000
3 and $t0,$t1,$t2 #若是想把$t1第一字節置爲0,那麼就可讓$t2中相應位置爲0
4 t2
5 0000 0000 0000 0000 0000 1101 0000 0000
6 #$t2能夠叫作掩碼

與AND對偶的操做是按位或(OR)

OR提供了一種將源操做數置一的方法,與AND類似,再也不詳細展開。

按位取反(NOT)

該操做只有一個操做數,把這個操做數中的1->0,0->1

MIPS中還有或非NOR(NOT OR)

XOR

相同取1,不一樣取0

 

 

3.決策指令

條件分支指令

相等條件分支
beg $s0,$s1,L1

若$s0和$s1中數值相等,則轉到標籤爲L1的語句

不相等條件分支
bne $s0,$s1,L1

若.......不相等,則轉到標籤爲L1的語句

無條件分支指令

當遇到這種指令時,程序必須分支

j L1

當遇到這條指令,則轉到標籤爲L1的語句

例:用機器語言表示C語言程序1

1 if( i == j )
2     f = g + h;
3 else
4     f = g - h;
1 #$s3=i,$s4=j
2 #$s0=g,$s1=h,$s2=f
3 bne $s3,$s4,Else        #若i!=j 則轉到Else
4 add $s0,$s1,$s2         #若i==j 則到這一步 f=g+h
5 j Exit                  #i==j段運行結束
6 Else: sub $s0,$s1,$s2   #i!=j f=g+h
7 Exit:                   #程序結束

選擇用bne而不是beg,由於bne經過測試分支的相反條件來體跳過if語句後邊的then部分,提升效率

case/switch

使用轉移地址表:由代碼中標籤所對應的地址構成的數組

程序跳轉-------->(索引)------>轉移地址表-------->(地址)-------->寄存器---------->(加載地址)-------->完成

爲了支持這種狀況,計算機提供了寄存器跳轉指令jr(jump regisiter),用來無條件跳轉到寄存器指定地址

(下下一節會詳細介紹jr語句)

4.循環

LOOP標記循環

例:用機器語言表示C語言程序2

1 while( save[i] == k)
2     i=i+1;
1 $t3=i,$t5=k,$6=save
2 LOOP:   sll $t1,$s3,2       #存放i的寄存器左移2位
3         add $t1,$t1,$t6     #把偏移地址與基址相加
4         lw  $t0,0($t1)      #取出save[i]中的數
5         bne $t0,$s5,Exit    #save[i]!=k->Exit
6         addi $s3,$s3,1      #i++
7         j   LOOP            #回到LOOP標記,從新運行
8 Exit:

i本來表明的是第i個數組元素,而按字節尋址是一次尋找一個字節

但爲何要把i*4???

 

小於則置位(set on less than)slt

若第一個寄存器小於第二個寄存器,則第三個寄存器置1,不然置0

1 slt $s0,$s3,$s4     #$s0 = 1 if $s3 < $s4
2 slti $t0,$s2,10     #$s0 = 1 if $s2 < 10

比較指令應該具備分清有符號數和無符號數的能力

有符號數操做(slt,slti):最高位爲1的數表明是一個複數,必定小於最高位爲0

無符號數操做(sltu,sltiu):最高位爲1,必定大於全部最高位爲0的數

補充:邊界檢查的捷徑

1 sltu $t0,$s1,$s2                #$t0=0 if $s1 >= length or $s1 < 0
2 beg  $t0,$zero,IndoexOutofBounds
相關文章
相關標籤/搜索