いつも忘れてしまう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で一度比較して | 1バイトに分割して比較する |
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での数値分岐はなんとかなりそう・・・^^