植物 植物
初心者講座:分岐命令

AOBA's Information Processing Education



1998/03/15

注意1:このページは、回線を切断した後でゆっくりご覧になってください(テキストを印刷する場合は、その取り扱いに注意してくださるようお願いします)。

注意2:背景が白地の画面を長時間見つめていると頭が痛くなってしまいますので、ここは背景をグレーにしています。


 今週のテーマに入る前に、先週説明したDC擬似命令について弱冠の補足をします。

 DC命令は、オペランドで指定した値の領域を確保(領域を確保した上に、プログラムの開始に先立って、オペランドで記述した値に初期化)する命令でしたね。

VAR DC 20 ; 10進数の20を1語(2バイト=16ビット)確保する

 VARで示される(1語の)領域は10進数の20です。1語は16ビットですので、COMETの主記憶には(0000000000010100)2と確保されます。
 だから、これを次のように記述しても同じことです。

VAR DC #0014 ; 16進数の0014(10進数の20)を1語確保する

 もう一度言いますが、’DC 20’と’DC #0014’は完全に同じ命令です

 ずっと以前にも説明しましたが、10進数と16進数は単なる表記上の違いであり、コンピュータ(ここではCOMET)内部ではすべて2進数で処理されます。
 実に当り前のことなのですが、なぜか、10進数で表現した値と16進数で表現した値をまったくの別物と理解している人が多いので注意しましょう。
 同じ理由で次の2つの命令もまったく同じです(COMETは2の補数で負数を表す)。

 DC −1 ; 10進数の−1=(1111111111111111)2
 DC #FFFF ; 16進数のFFFF=10進数の−1

 さて、ここからが今週のテーマ「分岐命令」の説明です。

 (CASLに限らず)普通のプログラムは、「処理」,「分岐」,「繰り返し」という3つの要素から構成されます。だけど、これまで説明した機械語命令は、すべて「処理」に当たる命令でした。
 もちろん「処理」だけのプログラムもありますが、やはり、「分岐」や「繰り返し」がないと、有効なプログラムとは言えないでしょう。

 「分岐」と「繰り返し」は以下のような構造でしたね。

図1

 この流れ図を日本語で表現した(擬似)プログラムに書き直します。

「分岐」
....(以上省略)
(1)条件判定を行い、条件を満足したら(満足しなければ)(3)へ分岐する(飛ぶ)
(2)処理を行う
(3)(流れ図にはない次の命令)
....(以下省略)

「繰り返し」
....(以上省略)
(1)処理を行う
(2)条件判定を行い、条件を満足したら(満足しなければ)(1)へ分岐する(飛ぶ)
(3)(流れ図にはない次の命令)
....(以下省略)

 この(擬似)プログラムで分かるように、”条件判定を行い、条件を満足したら(満足しなければ)(x)へ分岐する(飛ぶ)”という命令があれば「分岐」も「繰り返し」も実現することができます。
 CASLにもこれと同じことを行う命令があり、この命令を条件付き分岐命令と言います。

「条件付き分岐命令を使用したCASLプログラム例(分岐)」
EX   START
....(途中省略)
     SUB GR0,C1
     JZE NEXT     ; これが条件付き分岐命令
     ADD GR1,C1   ; これが上記流れ図における処理に当たる
NEXT LD  GR1,DATA ; これが次の命令に当たる
....(途中省略)
C1   DC  1
DATA DS  10
     END

 上図はGR0が0ならばNEXTラベルの命令(LD GR1,DATA)に分岐するプログラム例です。つまり、
 GR0が0の場合  −>GR1に1を加算しない(NEXTまでの全命令をバイパスする)
 GR0が0以外の場合−>GR1に1を加算する
を行いたい訳です。

 これまでラベルは、DSやDCの擬似命令に付くものと理解していたと思います。ところが上記のプログラム例のように機械語命令に付けることもでき、その場合は分岐命令の分岐先を示す目印のように使用します。

 CASLにおける条件付き分岐命令は次の4つだけです。

「条件付き分岐命令」
 JPZ 分岐先ラベル ; 0か正ならば分岐先ラベルへ分岐する
 JMI 分岐先ラベル ; 負ならば分岐先ラベルへ分岐する
 JNZ 分岐先ラベル ; 0以外ならば分岐先ラベルへ分岐する
 JZE 分岐先ラベル ; 0ならば分岐先ラベルへ分岐する

(注)”分岐先ラベル”はCASLで規定された正しい用語ではありません。ここでは分岐先を示すラベルという意味を出すために、あえてこのような用語を用いました。

 そしてこれら4種類の条件付き分岐命令に加え、条件判定なしに無条件に分岐する命令もあります。これを「無条件分岐命令」と言い、これと「条件付き分岐命令」と合わせて「分岐命令」と言います(用語は特に覚える必要はありません)。

「無条件分岐命令」
 JMP 分岐先ラベル ; 必ず分岐先ラベルへ分岐する

 さてここで、先のプログラムの分岐命令部分をもう一度以下に記します。

....(以上省略)
 SUB GR0,C1
 JZE NEXT ; 0ならばNEXT(ラベル)へ分岐
....(以下省略)

 JZEは”0ならば分岐先ラベルへ分岐する”命令ですが、何が0ならば分岐先ラベルへ分岐するのか考えてみましょう。

 この例では先の説明にもあったように、GR0が0ならばNEXTへ分岐します。
もし他のレジスタ(GR1〜GR4)と比較した条件判定を行いたいならば、JZE命令(というか条件付き分岐命令)の前の演算命令の第1オペランドを、比較したいレジスタにすればOKです。

(注)条件付き分岐命令の前の命令は、演算命令(算術演算命令や論理演算命令等)でさえあれば何でもよいのです。

 また、この例ではGR0から1減算していますが、レジスタの内容を変化させずに条件判定を行いたい場合は”SUB GR0,C0”等として、GR0から0を減算し(0を引いてもレジスタの内容は変化しない)、次の条件付き分岐命令に備えます。
 ここで重要なことは、条件付き分岐命令を正しく機能させるには、それ以前に演算命令が必要である、ということです。

(注)他の(高級)プログラム言語を知っている方にとっては、ちょっと変な感じを受けるかもしれません。

 ところで条件付き分岐命令の比較は、何もレジスタと定数0の間だけとは限りません。レジスタと主記憶(つまり1語の変数)との間で行うこともできます。
 ただしこれを行うためには、フラグレジスタと比較演算命令について知っていなければなりません。
 これについては来週説明しましょう。ではまた。