分岐とジャンプ

プログラムの流れを変える分岐とジャンプは実はプログラムカウンタ(PC)への操作です。通常は命令列に従って増加する一方のPCに、何らかの値をセットすることはその値を飛び先アドレスとした分岐またはジャンプにほかなりません。

ジャンプ(条件なし分岐)

条件判断なしにとにかくジャンプします。PCへの値のセットの仕方で3種類あります。

Operation Mnemonic inCode Opr2 Opr3 Opr4 Opr5 #bytes Opcode Ie Cy Cd
PC <- PC + RA JF RA 2 60 RA
PC <- PC – RA JB RA 2 61 RA
PC <- (PC) JMP addr addr 3 62 aa aa

簡単なところから。JMPは「絶対アドレスジャンプ」といい、オペランドがPCにそのままセットされ、それが飛び先アドレスになります。Opcode欄の「aa aa」にアドレスを4桁で指定してください。

JFは「前方相対アドレスジャンプ」で、この命令を実行した直後のPCの値(すなわち次の命令の先頭アドレス)に2桁の数値を加え、それが飛び先アドレスになります。JBは逆向きの「後方相対アドレスジャンプ」で、命令を実行した直後のPCの値から2桁の数値を引いて飛び先アドレスとします。Opcode欄の「RA」に00~99の値を指定してください。

コーディング例

Addr Data Label Opcode Operand Comment
0000 62 08 00 start: JMP hop ラベル”hop:”の0800番地にジャンプ

0800 60 18 hop: JF step ラベル”step:”の0820番地にジャンプ
0802 ?? (ここを0として下方向に数える)

0818 38 09 jump: IN 09
0820 61 04 step: JB jump ラベル”jump:”の0818番地にジャンプ
0822 ?? (ここを0として上方向に数える)

条件分岐

これがなければコンピュータじゃない、もっとも肝の部分といっていいでしょう。条件に合致していなければそのまま進み、条件に合致していたら動作を変える。つまりプログラムの流れを変える、ジャンプするということです。

Operation Mnemonic inCode Opr2 Opr3 Opr4 Opr5 #bytes Opcode Ie Cy Cd
PC <- PC + RA if SR is cc JFcc cc RA 2 4c RA
PC <- PC – RA if SR is cc JBcc cc RA 2 5c RA

ジャンプする方式は前述の「(前方・後方)相対アドレスジャンプ」と同じOpcode欄の「RA」で行います。

条件判定の部分を「c」入れます。下表を参考にしてください。

「cc」 「c」 意味 ステータスレジスタ(SR)の内容
EQ 0 Equal 等しい(=) Cd = 1(EQ)
NEQ 1 Not Equal 等しくない(≠) Cd ≠ 1(EQ)
GT 2 Greater Than より大きい(>) Cd = 0(GT)
GE 3 Greater Than or Equal to 以上(≧) Cd = 0(GT) または Cd =1(EQ)
LT 4 Less Than より小さい(<) Cd = 2(LT)
LE 5 Less Than or Equal to 以下(≦) Cd = 2(LT) または Cd =1(EQ)
ER 6 on Error エラーあり Cd = 3(ER)
NER 7 on No Errors エラーなし Cd ≠ 3(ER)
CY 8 on Carry 桁上げ・桁借りあり Cy > 0
NCY 9 on No Carry 桁上げ・桁借りなし Cy = 0

条件分岐は、比較や算術・論理演算などのステータスレジスタ(SR)が変化する命令の後に配置します。

コーディング例

Addr Data Label Opcode Operand Comment
0000 21 start: LDI.d 1
0001 75 50 loop: CMPI 50 Aと50を比較する
0003 40 10 JFEQ eq50 A=50ならラベル”eq50:”に分岐
0005 74 01 ADDI 1
0007 61 08 JB loop ラベル”loop:”にジャンプ

0015 99 eq50: HALT

補足

  • “JMP”は”Jump”(ジャンプ)の略です。
  • “JF”、”JB”はそれぞれ”Jump Forward”(ジャンプ・フォワード)、”Jump Backward”(ジャンプ・バックワード)の略です。
  • 飛び先はプログラム領域の範囲内に限るべきです。
  • この命令はステータスレジスタ(SR)を変化させません。