Categories: R10マイコン

Z80の分岐命令を整理しておく

いつも忘れてしまうZ80の分岐命令を整理しておきます。

1バイトの比較はフラグのみ変化できるCP命令を使用
2バイトの比較はCP命令が使えないのでキャリーフラグをセットしてSBC命令で比較する

▼分岐命令の種類
① JP  絶対アドレスで分岐
② JR  相対アドレスで分岐
③ CALL – RET  サブルーチンコール & リターンの3種類

▼分岐方法

大小比較 1バイト比較 (CP命令を使用) 2バイト比較  (SBC命令を使用)
レジスタにセット ① LD A, 11  比較される値をAレジにセット
② LD B, 12  比較する値をBレジにセット
③ CP命令で比較  → CP B
④ 分岐命令で分岐
①LD  DE,  1234  比較される値をDEレジにセット
②LD  BC,  1235  比較する値をBCレジにセット
③EX  DE, HL
④OR  A     キャリーフラグセット
⑤SBC  HL,  BC
A  > B
DE  > BC

JP NC, tmpラベル   ; NCで一度比較して
         :
tmpラベル:  JP NZ, ラベル  ;NZで比較する

1バイトに分割して比較する
(DとB, EとCを分けてDEとBCとして比較)
LD  A,  D
CP  B
JP  Z, tmpラベル
         :
tmpラベル:  JP  LD  A, E
CP  C
JP  Z, ラベル

A ≧ B
DE ≧ BC
JP NC, ラベル ← 同様
A = B
DE = BC
JP Z, ラベル ← 同様
A <> B
DE <> BC
JP NZ, ラベル ← 同様
A ≦ B
DE ≦ BC
JP C, ラベル ;<はCの比較で分岐
JP Z,ラベル ;≦がZの比較で分岐

← 同様

A < B
DE < BC
JP C, ラベル ← 同様
条件なし分岐
常に分岐 JP nnnn ← 2バイトのアドレス値又は(HL), (IX), (IY)等のレジスタ値を指定
常に分岐しない BRN BRanch Neverはあるの!?


▼フラグの変化
6809と違いLDでレジスタに値をロードしてもフラグは変化しないので必要ならばANDやOR命令を使いフラグを変化させなければいけない
LD  A, (HL)
AND  A                 ;フラグを変化させる
JP  Z, ラベル     ;ゼロならラベルにジャンプ

▼フラグレジスタ

⑦ S ⑥ Z ⑤ 未使用 ④ H ③ 未使用 ② P/V ① N ⓪ C

フラグレジスタの変更
6809のようにビットを直接AND, ORできない
LD  C, 変更したい8ビット
PUSH  BC
POP  AF
これでフラグレジスタのビットを任意に変更できるがAレジスタも変更されるので、
必要な場合は退避が必要。

キャリーフラグはセットしたり反転したりできる専用の命令がある。
反転 = CCF
セット = SCF
SCFでキャリーフラグをセットしてCCFで反転させてキャリーフラグをクリアする方法もある。

機械語 分岐命令の考え方
IF 条件 THEN ProgA ELSE ProgB ならば
10 IF 条件 THEN GOTO 40
20 ProgB
30 GOTO 50
40 ProgB
50 NextProg
のように条件がFalseなら次の行、TrueならGOTO どこどこのように書く

とりあえずこれだけあればZ80での数値分岐はなんとかなりそう・・・^^

 

kabekin