比較命令 比較命令

比較命令
„ 条件は一致・不一致だけではない
„ 値の大小関係を調べる命令も必要
• if (a>b) { … }
• while ( x <= w ) { … }
• for ( i=0; i<100; i++) { … }
など
比較命令
slt $Ri,$Rj,$Rk
‹ “ set on less than ”
‹ $Rj < $Rk ならば,$Ri ← 1 ( 00000000 00000000 00000000 00000001 )
さもなければ,$Ri ← 0 ( 00000000 00000000 00000000 00000000 )
( $Rj ≧ $Rk ならば )
slti $Ri,$Rj,C
‹ “ set on less than immediate ”
‹ $Rj < C ならば,$Ri ← 1 ( 00000000 00000000 00000000 00000001 )
さもなければ,$Ri ← 0 ( 00000000 00000000 00000000 00000000 )
( $Rj ≧ C ならば )
‹ 即値Cは16bitの2の補数表現のもとで
-32768~32767の範囲(-215~215-1)を指定できる。
1
比較命令の命令形式
slt $s1, $s2, $s3
(rd) (rs) (rt)
op
rs
$s2 <$s3 ならば $s1 ← 1
さもなければ $s1←0
rt
rd
shamt
funct
000000 10010 10011 10001 00000 101010
31
26 25
21 20
slti $s1, $s2, C
(rt) (rs)
op
16 15
rs
26 25
0
$s2 < C ならば $s1 ← 1
さもなければ $s1←0
rt
imm
C
001010 10010 10001
31
6 5
11 10
21 20
0
16 15
16bit,2の補数表現
slt,slti 命令でレジスタ間の比較を
行った後,どのように分岐させるか ?
比較結果はレジスタ$Riの内容(1か0)で知ることができる
レジスタ$Riが1(0でない)か0かで,条件分岐させる
$Rj < $Rk ならば分岐
slt
$Rj ≧ $Rk ならば分岐
$Ri, $Rj, $Rk
slt
bne $Ri, $zero, Label
$Ri, $Rj, $Rk
beq $Ri, $zero, Label
定数と比較する場合(slti命令)も同様
2
条件: if - then型
C プログラムの例
1: if ( u < v ) {
2: x = x+1 ;
3: }
u < v なら $t0=1
u≧v なら $t0=0
したがって,
$t0=0 ならば,if文から
脱出する
$gp
1
lw $s0, 0($gp)
# $s0 ← u
2
lw $s1, 4($gp)
# $s1 ← v
3
slt $t0, $s0, $s1
# $s0<$s1 (u<v) か?
4
beq $t0, $zero, exit
5
lw $s2, 8($gp)
# $s0 ← x
6
addi $s2, $s2, 1
# $s0 ← $s0 + 1
7
sw $s2, 8($gp)
# x ← $s0
8 exit:
u
v
x
条件: if - then - else 型
C プログラム
1: if ( u < v ) {
2: x = x+1 ;
3: } else {
4: x = x – 1;
5: }
u < v なら $t0=1
u≧ v なら $t0=0
したがって,
$t0=0 ならば,else部
を実行させる
$gp
u
1
lw $s0, 0($gp)
# $s0 ← u
2
lw $s1, 4($gp)
# $s1 ← v
3
slt $t0, $s0, $s1
# $s0<$s1 (u<v) か?
4
beq $t0, $zero, else
5
lw $s2, 8($gp)
# then部の処理
6
addi $s2, $s2, 1
# $s2 ← $s2 + 1
7
8
sw $s2, 8($gp)
b exit
# x ← $s2
9 else: lw $s2, 8($gp)
10
addi $s2, $s2, -1
11
sw $s2, 8($gp)
12 exit:
v
x
3
# else 部をスキップ
# else 部の処理
# $s2 ← $s2 -1
# x ← $s2
「等しい」を含む条件(≦,≧) はどのように記述すればよいか?
slt 命令では,「<」(小さいかどうか)しか判定できない。
条件 「a≦b」 の否定条件は 「a > b」 ← これなら,slt 命令で判定できる。
ただし,slt 命令の比較オペランド
の順序を考慮して,「b<a」の条件
を調べる。
したがって,「=」を含む大小関係を判定するには,その否定条件について,条
件判定をすればよい。
【例題】
レジスタ$s0の値がレジスタ$s1の値以下のとき($s0 ≦ $s1 のとき),
ラベルL1に分岐する命令列を示せ。
【解答】
条件「$s0 ≦ $s1」 の否定条件 → 条件「$s1 < $S0」
したがって,
slt $t0, $s1, $s0
beq $t0, $zero, L1
# $s1 < $s0 ならば $t0 ← 1
# $s1 ≧$s0 ならば $t0 ← 0
← $s1 ≧$s0 ならば L1 へ分岐
←
とすればよい。
4
「=」を含む条件判定: if - then型
C プログラムの例
1: if ( u <= v ) {
2: x = x+1 ;
3: }
条件「 u ≦ v 」は「=」を含むので,
否定条件「u > v」を考える
→ 条件「u > v」は slt 命令の
オペランドの順序を考慮して,
「v<u」 で条件判断する
1
lw $s0, 0($gp)
# $s0 ← u
2
lw $s1, 4($gp)
# $s1 ← v
3
slt $t0, $s1, $s0
# $s1<$s0 (v<u)か?
4
bne $t0, $zero, exit
5
lw $s2, 8($gp)
# $s0 ← x
6
addi $s2, $s2, 1
# $s0 ← $s0 + 1
7
sw $s2, 8($gp)
# x ← $s0
s1<$s0 (v<u)
であることに注意
8 exit:
$gp
v < u なら $t0=1
v ≧u なら $t0=0
したがって,
$t0=1(v < u)ならば,if 文から脱出する
u
v
x
繰返し: while 型
C プログラム
1: n=100 ;
2: while (n > 0) {
3:
文1 ;
4:
文2 ;
5:
・・・
6:
n=n -1;
7:
}
0 < n なら $t0=1
0≧n なら $t0=0
したがって,
$t0=0 ならば while 文
から脱出する
1
addi $s0, $zero,100 # $s0 ← 100
2
sw $s0, 0(gp)
# n ← $s0
3 L1:
lw $s0, 0(gp)
# $s0 ← n
4
slt $t0, $zero, $s0
# 0<n どうか
5
beq $t0, $zero, L2
# $t2=0なら脱出
6
(文1, 文2, ・・・, の処理)
7
lw $s0, 0(gp)
# $s0 ← n
8
addi $s0, $s0, -1
# $s0 ← $s0 -1
9
sw $s0, 0($gp)
# n ← $s0
b L1
# L1へ戻る
13:
14: L2:
$gp
5
n
繰返し: for 型
for 文は while 文で書き直せる
1: for ( n=0 ; n < 100 ; n++ ) {
2:
文1 ;
3:
文2 ;
5:
・・・
7:
}
1: n=0 ;
2: while (n<100) {
3:
文1 ;
4:
文2 ;
5:
・・・
6:
n=n +1;
7:
}
繰返し: for 型(while型で書くと)
1: n=0 ;
2: while (n<100) {
3:
文1 ;
4:
文2 ;
5:
・・・
6:
n=n +1;
7:
}
n<100 なら $t0=1
n≧100なら $t0=0
したがって,
$t0=0 ならば while 文
から脱出する
1
sw $zero, 0(gp)
#n←0
2 L1:
lw $s0, 0($gp)
# $s0 ← n
3
slti $t0, $s0, 100
# $s0と100 との比較
4
beq $t0, $zero, exit
5
(文1, 文2, ・・・, の処理)
6
lw $s0, 0($gp)
# $s0 ← n
7
addi $s0, $s0, 1
# $s0 ← $s0 + 1
8
sw $s0, 0($gp)
# n ← $t1
9
b L1
# L1へ戻る
14: exit:
$gp
6
n