整数演算命令 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に格納する 整数演算の例 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 で求まる) 1 用語 z オペコード(operation code の略) : 命令コード z オペランド(operand) : 演算対象(のデータ) − ソース(source:元): 被演算対象となるデータ − デスティネーション (destination:目的): 演算結果のデータ add $s0, $s1, $s2 # $s0←$s1+$s2 第2 ソースオペランド 第1ソースオペランド デスティネーションオペランド ソース レジスタ デスティネーション レジスタ オペコード 代入文 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 2 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 0 6 5 rsフィールド(5ビット) rtフィールド(5ビット) rdフィールド(5ビット) shamtフィールド(5ビット) ソースレジスタを示す ソースレジスタを示す デスティネーションレジスタ シフト命令でシフト量を示す $s2 (18) $s3 (19) を示す $s1 (17) 加算命令の場合は0 減算命令の命令形式 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 3 整数演算命令 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 C 001000 10010 10001 31 26 25 21 20 16 15 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 4 論理演算 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 論理演算命令 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 に格納する。 5 論理演算命令の命令形式 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 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に格納する 6 算術シフト演算 指定されたビット数,左あるいは右に算術シフトする z MIPSでは左論理シフト命令はあるが,左算術シフト命令はない (左シフトを行う場合は,左論理シフト命令を使う) z 右算術シフト(shift right arithmetic) はみ出したビットは捨てられ,空いた部分には符号ビットの値が入る 命令 : sra $Ri, $Rj, k レジスタ$Rjの内容を k ビット右に算術シフトした値を$Riに格納する 左シフトと数値との関係 整数 100(100) の2進表現 0000 0000 0000 0000 0000 0000 0110 0100 = 100(10) 2 ビット左にシフト 0000 0000 0000 0000 0000 0001 1001 0000 = 400(10) 整数 -100(100) の2進表現 1111 1111 1111 1111 1111 1111 1001 1100 = -100(10) 2ビット左にシフト 1111 1111 1111 1111 1111 1110 0111 0000 = - 400(10) n ビットの左シフト = 2n 倍 7 右算術シフトと数値との関係 整数 400(100) の2進表現 0000 0000 0000 0000 0000 0001 1001 0000 = 400(10) 2 ビット右に算術シフト 0000 0000 0000 0000 0000 0000 0110 0100 = 100(10) 整数 -400(100) の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での割ったときの商) 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 8 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 $gp # $t0 ← 5*a # $s1 ← 10*a # x ← $s1 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 ← 2*a+4*b-c # x ← $s3 9 a b c x
© Copyright 2024 ExpyDoc