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


計算機組成原理--10.5

1.計算機中指令的表示

前言

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

在接下來的學習中需要用的部分的寄存器,所以在這里先做簡單引入。

寄存器$s0~$s7映射到寄存器16~23,寄存器$t0~$t7映射到寄存器8~15.(這里s和t都只是標號,在之后的學習中我們會知道,s代表保留寄存器,t代表臨時寄存器)

指令格式

指令的布局形式叫做指令格式。

MIPS指令占32位,與數據字的位數相等。

數據字的定義:數據字,由於計算機使用的信息既有指令又有數據,所以計算機字可以代表指令,也可以代表數據。如果某字代表要處理的數據,則稱為 數據字;如果某字為一條指令,則稱為指令字-------百度百科

MIP字段

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

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

問題:如果有些指令需要常數的參與,例如取數操作那該怎么做?

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

但實際上,這種操作方法會出現問題,當參與操作的常數>32(2^5)時就會出現超出范圍的問題。因此又希望所有指令的長度一樣,又希望能夠有統一的指令格式,同時還要避免出現操作的常數太小的問題.......就出現了心得指令格式:

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

 

 

 

 


免責聲明!

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



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