[PP0906] 12. 条件分岐

プログラムでは、状態によって処理の流れを変えたいことがよくあります。C 言語でも if 文を使って、変数の値によって処理を変えることがあると思います。それを実現するための命令が条件分岐です。

命令 ニーモニック 命令長 意味
23 BZ 2 アキュムレータが 0 であれば PC 相対アドレスへ分岐
24 BNZ 2 アキュムレータが 0 でなければ PC 相対アドレスへ分岐

BZ と BNZ 命令は、PC 相対アドレスへ分岐します。つまり、相対アドレス指定方式によって実効アドレスを求めるわけです。具体的には、BZ または BNZ 命令の次の命令の位置を ±0 として、それより先の位置に分岐するならプラス、前の位置に分岐するならマイナスの値を指定します。マイナスの値を指定した場合には、ループを作ることになります。

それでは、条件分岐を使った簡単なプログラムを作ってみます。

int program[] =
{
  LI, 10,
  OUT,
  DEC,
  BNZ,-4,
  -1,
};

このプログラムでは、最初にアキュムレータに即値 10 をロードし、アキュムレータが保持する値を出力したあとデクリメントを繰り返し、アキュムレータの値が 0 になれば終了するものです。期待している出力結果は次のようになります。

0x0000000a(10)
0x00000009(9)
0x00000008(8)
0x00000007(7)
0x00000006(6)
0x00000005(5)
0x00000004(4)
0x00000003(3)
0x00000002(2)
0x00000001(1)

それでは、実際に命令を追加していきます。まずは BZ 命令からです。

case BZ:
  eaddr = memory[pc];
  pc = pc + 1;
  if (a == 0) pc = pc + eaddr;
  break;

今回のコードはちょっとセオリーから外れています。というのは、本来、実効アドレスを格納するための変数である eaddr を、実効アドレスではない命令の第 2 ワードを格納するためにだけ使っているからです。これに深い意味はありませんが、一時的な値を入れておく適当な変数なかったために eaddr を借用しただけで、本来であれば別の変数を定義したほうがよいかもしれません。

ともかく、第 2 ワードを eaddr に読み込み、アキュムレータ A が 0 の場合にかぎり、その時点での PC(BZ 命令の次の命令を指しているはず)に eaddr を加えています。

BNZ 命令に関しては、if 文の条件式が変わるだけで、あとは同じです。

case BNZ:
  eaddr = memory[pc];
  pc = pc + 1;
  if (a != 0) pc = pc + eaddr;
  break;

今回は、アキュムレータが 0 かどうかだけを判定材料にする条件分岐命令だけを作りました。実際には、インデックスレジスタを判定材料にしたり、プラスかマイナスかを判定するような条件分岐命令もあったほうが、プログラミングは楽になります。

この記事のトラックバックURL:

http://www.kijineko.co.jp/trackback/527
このエントリーを含むはてなブックマーク