MIPSの主記憶の構成 z 主記憶の各ワード(語)は,番地(アドレス)によって識別され る。(番地はbyte単位で付けられる) 語(ワード)の番地 プロセッサからは 4の倍数の番地 で各ワードを指定 する byte単位での番地 0番地 0番地 1番地 2番地 3番地 4番地 4番地 5番地 6番地 7番地 8番地 8番地 9番地 10番地 11番地 ………… 4n番地 4n 4n+1 4n+2 4n+3 ………… 1073741820番地 (230-4) 230-4 230-3 230-2 230-1 最初のワードの番地は0番地,次は4番地,次は8番地... ,となる MIPSのレジスタ z 32個のレジスタ – 機械語では0から31までの番号で識別される – アセンブラ言語では名前(レジスタ名)で識別できる z 使用目的により32個のレジスタを分類(規約) – レジスタ $s0,$s1,$s2,……,$s7 • C言語などの高級言語でプログラム中の変数の値を保持する目的 – レジスタ $t0,$t1,$t2,……,$t7 • 演算の途中での一時的なデータを保持する目的 – レジスタ $zero • 特別なレジスタで,常に 0 を値としてもつ (どのような値を書き込んでも,値は0のまま = データは保存できない) 1 MIPSのレジスタ番号とレジスタ名 レジスタ番号 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 レジスタ名 $zero $at $v0 $v1 $a0 $a1 $a2 $a3 $t0 $t1 $t2 $t3 $t4 $t5 $t6 $t7 レジスタ番号 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 レジスタ名 $s0 $s1 $s2 $s3 $s4 $s5 $s6 $s7 $t8 $t9 $k0 $k1 $gp $sp $fp $ra ※ アセンブリ言語では,レジスタ名で表記する 例 変数 a と b の値を交換するプログラム アセンブリ言語のプログラム C言語のプログラム w=a; a=b; b=w; $gp a 1 2 lw $t0, 0($gp) sw $t0,8($gp) w = a; 3 4 lw $t0, 4($gp) sw $t0, 0($gp) a = b; 5 6 lw $t0, 8($gp) sw $t0, 4($gp) b = w; これは説明用の行番号 b w ある変数の値を別の変数に代入するには, ロード命令とストア命令を使い,レジスタを 経由しなければならない 2 代入文の意味 「代入文」 変数 = 式 ; 「式」: 単独の定数や変数,配列要素,及び それらを演算記号で結合したもの。 記号「=」は,右辺の式の「値」を左辺の変数に「格納」するという作用をもつ。 a=5 ; a 5 b=8; b 8 h=4; h 4 s=(a+b)* h / 2; s 26 右辺の式の値を求めてから,変数に格納する。 整数演算命令 z 加算命令(add instruction) add $Ri, $Rj, $Rk 動作 : $Ri ← $Rj + $Rk レジスタ$Rjと$Rkの値の和をRiに格納する z 減算命令(subtract instruction) sub $Ri, $Rj, $Rk 動作 : $Ri ← $Rj - $Rk レジスタ$Rjと$Rkの値の差をRiに格納する 3 整数演算の例 z $s0 ← $s1 + $s2 + $s3 add $s0, $s1, $s2 add $s0, $s0, $s3 # $s0 ← $s1 + $s2 # $s0 ← $s0 + $s3 # 以降の文字列は コメント z $s2 ← $s0 + 2×$s1 add $s2, $s0, $s1 add $s2, $s2, $s1 # $s2 ← $s0 + $s1 # $s2 ← $s2 + $s1 = $s0 + 2×$s1 ($s1の2倍の計算は $s1+$s1 で求まる) 用語 z オペコード(operation code の略) : 命令コード z オペランド(operand) : 演算対象(のデータ) − ソース(source:元): 被演算対象となるデータ − デスティネーション (destination:目的): 演算結果のデータ add $s0, $s1, $s2 # $s0←$s1+$s2 第2 ソースオペランド 第1ソースオペランド デスティネーションオペランド オペコード 4 ソース デスティネーション 代入文 x = 2 * a + 4 * b - c のプログラム (x, a, b, c は変数) 1 2 3 4 5 6 7 8 9 lw $s0, 0($gp) add $s0, $s0, $s0 lw $s1, 4($gp) add $t0, $s1, $s1 add $t0, $t0, $t0 add $t0, $s0, $t0 lw $s2, 8($gp) sub $s3, $t0, $s2 sw $s3, 12($gp) # $s0 ← a # $s0 ← a+a $gp # $s1 ← b # $t0 ← 2*b # $t0 ← 4*b # $t0 ← 2*a+4*b # $s2 ← c # $s3 ← 2*a+4*b-c # x ← $s3 a b c x 加算命令の命令形式 add $s1,$s2,$s3 # $s1← $s2+$s3 第2ソースレジスタ(rt) 第1ソースレジスタ(rs) デスティネーションレジスタ(rd) オペコード(op) functフィールド(6ビット) 命令の詳細機能を示す: 加算指定 opフィールド(6ビット) 命令の分類を表す:演算命令 op rs rt rd shamt funct 000000 10010 10011 10001 00000 100000 31 26 25 21 20 16 15 11 10 6 5 0 rsフィールド(5ビット) rtフィールド(5ビット) rdフィールド(5ビット) shamtフィールド(5ビット) ソースレジスタを示す ソースレジスタを示す デスティネーションレジスタ シフト命令でシフト量を示す $s2 (18) $s3 (19) を示す $s1 (17) 加算命令の場合は0 5 減算命令の命令形式 sub $s1,$s2,$s3 # $s1← $s2-$s3 第2ソースレジスタ(rt) 第1ソースレジスタ(rs) デスティネーションレジスタ(rd) functフィールド(6ビット) 命令の詳細機能を示す: 減算指定 opフィールド(6ビット) 命令の分類を表す:演算命令 op rs rt rd shamt funct 000000 10010 10011 10001 00000 100010 31 26 25 21 20 16 15 11 10 6 5 0 rsフィールド(5ビット) rtフィールド(5ビット) rdフィールド(5ビット) shamtフィールド(5ビット) ソースレジスタを示す ソースレジスタを示す デスティネーションレジスタ シフト命令でシフト量を示す $s2 (18) $s3 (19) を示す $s1 (17) 減算命令の場合も0 整数演算命令 z 即値加算命令(add immediate instruction) addi $Ri, $Rj, C 動作 : $Ri ← $Rj + C - レジスタ$Rjと即値(定数)Cの値の和をRiに格納する。 - 即値Cは16bitの2の補数表現のもとで -32768~ 32767の範囲(-215~215-1)を指定できる。 - 定数の減算は C に負の値を使えばよい。 addi $s1, $s2, C (rt) (rs) op # $s1← $s2 + C rs rt imm 001000 10010 10001 31 26 25 21 20 16 15 6 C 0 整数演算命令の使い道 z レジスタのデータセット(16bitデータ,2の補数) addi $Ri, $zero, 128 : $Ri ← 128 z レジスタ間のデータ移動(コピー) add $Ri, $Rj, $zero : $Ri ← $Rj + 0 z 符号反転 : $Ri ← -$Rj sub $Ri, $zero, $Rj z 定数の減算 addi $Ri, $Rj, -50 : $Ri ← $Rj -50 論理演算 z 論理積 0100 0110 1010 0110 1100 1100 1010 0101 & 0000 0000 0000 0000 1111 1111 1111 1111 0000 0000 0000 0000 1100 1100 1010 0101 z 論理和 0100 0110 1010 0110 1100 1100 1010 0101 | 0000 0000 0000 0000 1111 0000 1111 0000 0100 0110 1010 0110 1111 1100 1111 0101 z 排他的論理和 0100 0110 1010 0110 1100 1100 1010 0101 0000 0000 0000 0000 1111 0000 1111 0000 0100 0110 1010 0110 0011 1100 0101 0101 7 論理演算命令 z 論理積命令(and instruction) and $Ri, $Rj, $Rk 動作 : $Ri ← $Rj & $Rk - レジスタ$Rjと$Rkの論理積を$Riに格納する。 z 論理和命令(or instruction) or $Ri, $Rj, $Rk 動作 : $Ri ← $Rj | $Rk - レジスタ$Rjと$Rkの論理和を$Riに格納する。 z 排他的論理和命令(exclusive-or instruction) xor $Ri, $Rj, $Rk 動作 : $Ri ← $Rj $Rk - レジスタ$Rj と$Rkの排他的論理和を$Ri に格納する。 論理演算命令の命令形式 and $s1,$s2,$s3 (rd) (rs) (rt) op # $s1← $s2 & $s3 rs rt rd shamt funct 000000 10010 10011 10001 00000 011000 31 26 25 21 20 16 15 or $s1,$s2,$s3 op 0 6 5 11 10 # $s1← $s2 | $s3 rs rt rd shamt funct 000000 10010 10011 10001 00000 011001 31 26 25 21 20 16 15 xor $s1,$s2,$s3 op 6 5 11 10 0 # $s1← $s2 $s3 rs rt rd shamt funct 000000 10010 10011 10001 00000 011010 31 26 25 21 20 16 15 8 11 10 6 5 0 論理シフト演算 指定されたビット数,左あるいは右に論理シフトする z 左論理シフト(shift left logical) 命令 : sll $Ri, $Rj, k レジスタ$Rjの内容を k ビット左に論理シフトした値を$Riに格納する z 右論理シフト(shift right logical) 命令 : srl $Ri, $Rj, k レジスタ$Rjの内容を k ビット右に論理シフトした値を$Riに格納する 算術シフト演算 指定されたビット数,左あるいは右に算術シフトする z MIPSでは左論理シフト命令はあるが,左算術シフト命令はない (左シフトを行う場合は,左論理シフト命令を使う) z 右算術シフト(shift right arithmetic) はみ出したビットは捨てられ,空いた部分には符号ビットの値が入る 命令 : sra $Ri, $Rj, k レジスタ$Rjの内容を k ビット右に算術シフトした値を$Riに格納する 9 左シフトと数値との関係 整数 100(10) の2進表現 0000 0000 0000 0000 0000 0000 0110 0100 = 100(10) 2 ビット左にシフト 0000 0000 0000 0000 0000 0001 1001 0000 = 400(10) 整数 -100(10) の2進表現 1111 1111 1111 1111 1111 1111 1001 1100 = -100(10) 2ビット左にシフト 1111 1111 1111 1111 1111 1110 0111 0000 = - 400(10) n ビットの左シフト ⇔ 2n 倍 右算術シフトと数値との関係 整数 400(10) の2進表現 0000 0000 0000 0000 0000 0001 1001 0000 = 400(10) 2 ビット右に算術シフト 0000 0000 0000 0000 0000 0000 0110 0100 = 100(10) 整数 -400(10) の2進表現 1111 1111 1111 1111 1111 1110 0111 0000 = - 400(10) 2 ビット右にシフト 1111 1111 1111 1111 1111 1111 1001 1100 = -100(10) n ビットの右算術シフト ⇔ 2-n 倍(2nでの割ったときの商) 10 rd シフト命令の命令形式 rt sll $s1, $s2, 3 op # $s1← $s2 << 3 rs rt rd shamt funct 000000 00000 10010 10001 00011 000000 31 26 25 21 20 16 15 0 6 5 11 10 シフト量はshamt (shift amount) フィールドで指定 ※ rs フィールドは使われないので何でもよい。ここでは 00000 としてある。 srl $s1,$s2, 8 op rs # $s1← $s2 >> 8 rt rd shamt funct 000000 00000 10010 10001 01000 000010 31 26 25 21 20 16 15 # $s1← $s2 >> 4 (算術シフト) sra $s1,$s2, 4 op rs 0 6 5 11 10 rt rd shamt funct 000000 00000 10010 10001 00100 000011 31 26 25 21 20 16 15 6 5 11 10 0 代入文 x = 10 * a のプログラム (シフト命令使用) 1 2 3 4 5 lw $s0, 0($gp) sll $t0, $s0, 2 add $t0, $t0, $s0 sll $s1, $t0, 1 sw $s1, 4($gp) # $s0 ← a # $t0 ← 4*a # $t0 ← 5*a # $s1 ← 10*a # x ← $s1 11 $gp a x 代入文 x = 2 * a + 4 * b - c のプログラム (シフト命令使用) 1 2 3 4 5 6 7 8 lw $s0, 0($gp) sll $s0, $s0, 1 lw $s1, 4($gp) sll $s1, $s1, 2 add $s3, $s0, $s1 lw $s2, 8($gp) sub $s3, $s3, $s2 sw $s3, 12($gp) # $s0 ← a # $s0 ← 2*a $gp # $s1 ← b # $s1 ← 4*b # $s3 ←2*a+4*b # $s2 ← c # $s3 ← a+4*b-c # x ← $s3 12 a b c x
© Copyright 2024 ExpyDoc