分岐命令 条件判断(if 文)や繰返し(for 文,while 文)の制御構造 はどのようにつくるか 制御構造を実現するための命令 • 分岐命令(条件分岐命令,無条件分岐命令) • 比較命令 プログラムの制御構造(C言語) 条件判定: if - then - else 型 条件判定: if - then 型 条件 不成立 成立 条件 不成立 成立 命令列 命令列 1 1 命令列 2 プログラムの制御構造(C言語) 条件判定: do - while 型 繰返し: while 型 成立 条件 命令列 命令列 条件 成立 不成立 ( for 文 はwhile型の特殊な場合 ) 通常の実行では,実行した命令の次の番地(アドレス)の命令が 実行される 繰返しや条件判定などの制御構造を作るには,任意の番地に 分岐(ジャンプ)できる命令が必要になる 条件を判定し,条件の成立・不成立によって次に実行する命令 の番地を変更する命令 (条件分岐命令 / 条件ジャンプ命令) : ただし条件によらず,「常に分岐 / ジャンプ」する命令(無条件分岐/ 無条件ジャンプ命令)もある。 分岐 / ジャンプ先の番地を指定するにはラベル(label)を 用いる 2 ラベル(label) ラベル: 命令やデータが配置されている主記憶上の番地 につけられた名前 1000 add $s0, $s0, $s1 add $s0, $s0, $s1 1004 addi $s4, $zero, 1 addi $s4, $zero, 1 1008 add $s1, $s1, $s0 L1: add $s1, $s1, $s0 1012 sub $s0, $s0, $s4 sub $s0, $s0, $s4 1016 bne $s0, $s4, 1008 bne $s0, $s4, L1 ラベル定義 ラベル参照 ※ ラベルはアセンブラによって主記憶の番地に変換される 条件分岐命令(1) 一致(= 条件)分岐 beq $Ri,$Rj,Label “ branch on equal ” $Ri と $Rj が等しければ,ラベル Label に分岐 さもなければ,次のアドレスの命令を実行 … beq $s1, $s0, L1 … … L1: … 3 条件分岐命令(2) 不一致(≠ 条件)分岐 bne $Ri,$Rj,Label “ branch on not equal ” $Ri と $Rj が等しくなければ,ラベル Label に分岐 さもなければ,次のアドレスの命令を実行 … bne $s1, $s0, L2 … … L2: … 無条件分岐命令 無条件分岐 b Label “ branch ” 無条件で(常に),ラベル Label に分岐 … b L3 … … L3: … 4 条件: if - then型 C プログラム 1: if ( v == w ) { 2: x = x+1 ; 3: } 1 lw $s0, 0($gp) # $s0 ← v 2 3 lw $s1, 4($gp) bne $s0, $s1, exit # $s1 ← w 4 lw $s3, 8($gp) # $s0=$s1ならば, 5 6 addi $s3, $s3, 1 sw $s3, 8($gp) # $s3 ← $s3 + 1 # $s0≠$s1 かどうか? # x ← $s3 7 exit: 条件判定の扱い プログラミング言語 : 成立したら次の文を実行 $gp アセンブラ言語(機械語命令) : 成立したら分岐する v w → アセンブラ言語では 逆の条件で調べたほうが プログラム構造は考えやすい x 条件: if - then - else 型 C プログラム 1: if ( v == w ) { 2: x = x+1 ; 3: } else { 4: x = x – 1; 5: } $gp v w x # $s0 ← v 1 lw $s0, 0($gp) 2 3 4 5 lw $s1, 4($gp) # $s1 ← w bne $s0, $s1, else # $s0≠$s1かどうか? lw $s2, 8($gp) # $s2 ← x addi $s2, $s2, 1 # $s2 ← $s2+1 6 sw $s2, 8($gp) # x ← $s2 b exit lw $s2, 8($gp) addi $s2, $s2, -1 sw $s2, 8($gp) # else 部をスキップ 7 8 else: 9 10 11 exit: 5 # $s2 ← x # $s2 ← $s2 -1 # x ← $s2 分岐命令の命令形式 「現在のPCの値」は現在実行し ている命令の次の命令の番地 になっていることに注意 ※ 分岐先の番地は現在のPCの値からのオフセット(変位;何番地離れて いるか)で指定する 命令の先頭番地は (「何命令前か,何命令後か」 という指定形式:PC相対指定) beq $Ri, $Rj, Label op rs rt address(offset) 000100 $Ri $Rj offset(2の補数表現) 31 PCの値はbeq命令の 次の命令の番地を指し ているから 4番地ごとだから 26 25 21 20 0 16 15 {(Label の番地)– 4 –(この命令のある番地)}÷4 bne $Ri, $Rj, Label op rs rt 000101 $Ri $Rj 31 26 25 op b Label 000100 31 21 20 rs 16 15 rt 00000 26 25 address(offset) offset(2の補数表現) 00000 21 20 0 address(offset) offset(2の補数表現) 16 15 0 b 命令は beq 命令で,$Ri=$Rj=$zero としたもの ( $zero=$zero だから常に成立) 分岐先アドレス(offset)の指定(後方の指定) 1000番地のbeq命令実行時 には,PCの値はすでに+4 さ れている 31 904 0 lw $t0,0($t1) (1104– 4 –1000)÷4 = 25 PC PC+4 1000 1004 beq $s1,$s2,25 add $t0,$t1,$t2 1104 sub $t0,$t1,$t2 1104番地に 分岐しようと する場合 分岐オフセット 100÷4=25 (25命令先) 次PC(分岐時) 分岐命令の次の命令から数えて(「現在のPCの値」が基準になることに 注意),25命令後(beq 命令の位置から数えると,26命令後方) 6 分岐先アドレス(offset)の指定(前方の指定) 31 次PC(分岐時) 分岐オフセット -100÷4=-25 904 PC PC+4 (25命令前) 0 lw $t0,0($t1) 1000 1004 beq $s1,$s2,-25 add $t0,$t1.$t2 1104 sub $t0,$t1,$t2 904番地に 分岐しようと する場合 (904– 4 –1000)÷4 = -25 分岐命令の次の命令から数えて(「次の命令」の位置が基準になることに 注意),25命令前(beq 命令の位置から数えると,24命令前) 例 1200番地 beq $s0, $s1, L1 (ラベルL1は1264番地に対応するものとする) op rs 000100 31 rt 10000 26 25 address(offset) 0000000000001111 10001 21 20 16 15 0 分岐先は,このbeq命令の次の命令から15 命令先にあるので,オフセットは 15 となる 16進表記 : 1211000F (1264-4-1200)/4=15 として計算できる 例 6400番地 bne $s0, $s1, L2 (ラベルL2は6144番地に対応するものとする) op rs 000101 31 rt 10000 26 25 address(offset) 1111111110111111 10001 21 20 16進表記 : 1611FFBF 16 15 0 分岐先は,このbeq命令の次の命令から65 命令前にあるので,オフセットは -65となる (6144-4-6400)/4=-65 として計算できる 7
© Copyright 2024 ExpyDoc