5. 反復処理

条件分岐による反復処理を行うと,さまざまな計算が実現できます.

基本的な枠組み

以下の枠組みによって,指定された条件を満たすまで,反復処理を行います.
  1. 計算をする
  2. 条件を満たしているならば,プログラムを終了する
  3. そうでなければ(条件を満たしていないならば)1の計算に戻る

基本的な枠組み


反復処理の例 "1から10までの和"

反復処理を使ったプログラムの例として, "1から10までの和" を計算するプログラムを考えてみます.下図の左側が LMC で実行できるプログラムです.このプログラムは教科書 図8.2 (下の図の右側)のプログラムを Littele Man Computer (LMC) 用に書き直したものです.

対応関係

各命令の対応関係は以下のようになっています.

LDA ADD STA SUB BRZ BRA OUT HLT
load add store subtract jumpzero jump write halt

LMCの命令セットについては,Little Man Computerシミュレータの命令セットをみてください.

0. プログラムの入力

以下のプログラムをプログラム領域にコピー&ペーストして,"Submit"ボタンを押して,メインメモリに読み込んでください.

プログラムの入力

1. "STEP"によるプログラムの実行

ここでも"STEP"をクリックして1命令ずつ実行して行きます.最初の状態では"PROGRAM COUNTER"と"ACCUMURATOR"の値は,ともに「0」となっています.

"STEP"によるプログラムの実行

2. "LDA 11" の実行

0番地の命令は "511 (LDA 11)" です.メインメモリの11番地の値「0」を "ACCUMULATOR" に読み込みます.

"LDA 11" の実行

3. "ADD 12" の実行

1番地の命令は "112 (ADD 12)" です."ACCUMULATOR" の値である「0」にメインメモリの12番地の値「10」を加えて,結果の値「10」を "ACCUMULATOR" に格納します.

"ADD 12" の実行

4. "STA 11" の実行

2番地の命令は "311 (STA 11)" です."ACCUMULATOR" の値「10」をメインメモリの11番地に書き出します.

"STa 11" の実行

5. "LDA 12" の実行

3番地の命令は "512 (LDA 12)" です.メインメモリの12番地の値「10」を "ACCUMULATOR" に読み込みます.

"LOAD 11" の実行

6. "SUB 13" の実行

4番地の命令は "213 (SUB 13)" です."ACCUMULATOR" の値「10」からメインメモリの13番地の値「1」を引き,結果の値「9」を "ACCUMULATOR" に格納します.

"SUB 13" の実行

7. "STA 12" の実行

5番地の命令は "312 (STA 12)" です."ACCUMULATOR" の値「9」をメインメモリの12番地に書き出します.

"STA 12" の実行

8. "BRZ 8" による条件分岐

6番地の命令は "708 (BRZ 8)" です."ACCUMULATOR" の値がゼロだった場合,"PROGRAM COUNTER" の値を「8」にして,プログラムの実行を8番地にジャンプします.この段階では "ACCUMULATOR" の値は「9」であり,ゼロではないので "PROGRAM COUNTER"の値は1増えて「7」になります.

"BRZ 8" による条件分岐

実行が進むにしたがって,5〜7の操作によって12番地の値が1つずつ小さくなり,ゼロになるときが訪れます.

9. "BRA 0" による無条件ジャンプ

7番地の命令は "600 (BRA 0)" です.無条件で "PROGRAM COUNTER" の値を「0」にして,プログラムの実行を0番地にジャンプします.

"BRA 0" による無条件ジャンプ

1. (2回目) 0番地からのプログラム実行

ここでは"PROGRAM COUNTER"の値は「0」となっています.ただしメインメモリの11番地と12番地の値が,最初の状態とは異なっていることに注意する必要があります.

0番地からのプログラムの実行

2. (2回目) "LDA 11" の実行

0番地の命令は "511 (LDA 11)" です.メインメモリの11番地の値「0」を "ACCUMULATOR" に読み込みます.

"LDA 11" の実行

3. (2回目) "ADD 12" の実行

1番地の命令は "112 (ADD 12)" です."ACCUMULATOR" の値である「0」にメインメモリの12番地の値「10」を加えて,結果の値「10」を "ACCUMULATOR" に格納します.

"ADD 12" の実行

4. (2回目) "STA 11" の実行

2番地の命令は "311 (STA 11)" です."ACCUMULATOR" の値「10」をメインメモリの11番地に書き出します.

"STa 11" の実行

5. (2回目) "LDA 12" の実行

3番地の命令は "512 (LDA 12)" です.メインメモリの12番地の値「10」を "ACCUMULATOR" に読み込みます.

"LOAD 11" の実行

6. (2回目) "SUB 13" の実行

4番地の命令は "213 (SUB 13)" です."ACCUMULATOR" の値「10」からメインメモリの13番地の値「1」を引き,結果の値「9」を "ACCUMULATOR" に格納します.

"SUB 13" の実行

7. (2回目) "STA 12" の実行

5番地の命令は "312 (STA 12)" です."ACCUMULATOR" の値「9」をメインメモリの12番地に書き出します.

"STA 12" の実行

8. (2回目) "BRZ 8" による条件分岐

6番地の命令は "708 (BRZ 8)" です."ACCUMULATOR" の値がゼロだった場合,"PROGRAM COUNTER" の値を「8」にして,プログラムの実行を8番地にジャンプします.この段階では "ACCUMULATOR" の値は「9」であり,ゼロではないので "PROGRAM COUNTER"の値は1増えて「7」になります.

"BRZ 8" による条件分岐

実行が進むにしたがって,5〜7の操作によって12番地の値が1つずつ小さくなり,ゼロになるときが訪れます.

9. (2回目) "BRA 0" による無条件ジャンプ

7番地の命令は "600 (BRA 0)" です.無条件で "PROGRAM COUNTER" の値を「0」にして,プログラムの実行を0番地にジャンプします.

"BRA 0" による無条件ジャンプ

10. 1〜9 の反復と終了

以上のように1〜9の処理が反復されます.2回目の反復が終わった際には,以下のようになります.

0番地からのプログラムの実行

このプログラムの実行によって,メインメモリ上の11〜13番地の値は,以下のようになることがわかります.

この反復が途切れるのは,「8. "BRZ 8"による条件分岐」で"ACCUMULATOR"の値が「0」(ゼロ)になる場合で,プログラムの実行は8番地にジャンプします.その直前で「7. "STA 12" の実行」を実行していることから,12番地の値が「0」となる状態であり,その際に11番地は「55」になっています.

反復の終了

11. "LDA 11" の実行

8番地の命令は "511 (LDA 11)" です.メインメモリの11番地の値「55」を "ACCUMULATOR" に読み込みます.

"LOAD 11" の実行

12. "OUT" による出力

9番地の命令は "902 (OUT)" です."ACCUMULATOR" の値「55」を出力します.

"OUT" の実行

13. "HLT" によるプログラムの終了

10番地の命令は "000 (HLT)" です.HLT命令によって,プログラムが終了します."OUTPUT"には1から10までの和である「55」が表示されています.

"HLT" によるプログラムの終了

プログラムの終了時には,以下のようになります.

プログラムの終了時