6800の分岐命令(ベーシックマスター開発 その30)
6800には豊富な分岐命令がある。複数の条件フラグを参照する分岐命令もあり、プログラミングを楽にしてくれる……はずなのだけど、うっかりすると罠にハマってしまう。実際ハマった。
解説資料も少なくて、初学者の参考になるようなサイトも見つけきれなかった。そこで6800の分岐命令の解説資料を書いておく。いまどき6800の初学者が存在するのかわからんけど。
分岐命令の詳細はMC6800のマニュアルに書かれている。日立ベーシックマスターのマニュアルにも解説はある(バグもあるが)。
M6800 Microprocessor Applications Manual 1-32 より引用
だけど、これだけではわかりにくいので、分岐条件を表にして整理してみた。
1バイトの符号なし比較と分岐
符号なし比較は簡単である。SUB/CMP命令でレジスタからメモリの値を引いて、C/Zフラグを見れば良い。CとZ両方を見るBHI/BLSもあるので、全パターンが1分岐命令で判断できる。
CPX/LDX/STX命令でもZフラグは立つので、2バイトの数値が等しいか・等しくないかは簡単に比較できる。
CPX/LDX/STXではCフラグは変化しないので大小関係はわからないが、変化しない方が多倍長演算が楽なのでこの仕様になったのだろう。
1バイトの符号あり比較と分岐
符号ありの場合は、結果の正負とオーバーフローの有無の両方を見ないといけない。
幸い、6800の分岐命令は両方を見て判断してくれるので全パターンを1命令で判断できる。
AccへのSUB/CMP命令の直後に下の表を見ながら分岐命令を書くだけで良い。楽ちんである。
複数の条件が絡むので、表にしないと実にわかりにくい。実際、I/O誌にも「意外とアヤフヤで使っている人の多い 条件分岐の完全理解」(I/O 1981年11月号 P.242)という記事が載ったほどである。
「意外とアヤフヤで使っている人の多い 条件分岐の完全理解」I/O 1981年11月号 P.243より引用
符号あり数値の正負判定
符号ありの数値が正(>=0)か負(<0)かを見るには符号ビット(bit 7)を見れば良い。これはBPL/BMIで判断できる。 LDX/STXでもNフラグは変化するので、正負だけなら2バイトの比較も簡単だ。 CPX #0やLDX/STXの後なら、Zも使えるので、2命令使えばZ>0もわかる。
LDX Var
BEQ EQUAL ; Z=0
BPL PLUS ; Z>0
... ; Z<0
実は正負だけなら、2バイト目を見る必要すらないので、TST命令で最初のバイトだけ調べても良い。TSTは遅いので、レジスタを壊しても良いならLDA/LDXの方が早い。
TST Var
BPL PLUS ; Z>=0
... ; Z<0
2バイトの比較と分岐命令
2バイトの比較はMC6800では鬼門である。MC6809にはCMPD命令があり、MC6301にもCPDがあるので2バイト比較は1バイト比較と同様に行える。
しかし、MC6800では限られた場合を除き、1バイト単位で比較しなければならない。
もっとも、MC6809/MC68HC11であっても、3バイト以上の多倍長演算では面倒臭い比較作業が必要になる。
6809用のCコンパイラであるacwjも、LONG(4bytes)の比較の部分には、// XXX This isn't right and I need to fix itなどと書かれていたりする。
2バイトの符号なし比較と分岐
さて、MC6800での符号無し・2バイトの比較表は以下の通りである。
1バイト比較と違うのは、上位バイトを見ただけでは判断できない場合があるので、2バイト目も見ないといけない場合がある、ということである。
例えば、2バイトの数値が0と等しいかどうかは、上位1バイトを見ただけではわからない。上位が0であっても下位は0でないかもしれない。
(逆に上位が0でなければ、0でないことはわかる)
したがって、0と等しいかの判断は以下のようにプログラムする。AとBをORできる命令があれば楽なんだけど、そんな命令はないので面倒なことになっている。
(ABA/CBA/SBAが有るのだから、AND/OR/EORも作って欲しかった)
TSTB
BNE NotEqual
TSTA
BNE NotEqual
... ; ==0
2バイトの符号あり比較と分岐
以下は2バイト符号ありの場合である。やはり、上位バイトだけを見たのでは結果がわからない場合がある。
L<=R の場合、下記のようなコードになる。1バイト比較では1命令で判断できたが、2バイト比較では分岐命令を2-3命令必要とするので、遅くなるし、わかりにくい。
LDAB L+1
LDAA L
SUBB R+1
SBCA R
BGT False
BNE True
TSTB
BNE False
True: :
False: :
上位バイトを見ただけで判断できる場合もあり、それは A>=M (BGE) と A<M (BLT)の場合である。これはコンパイラの最適化のテクニックとして使える。
日立ベーシックマスター取扱説明書のバグ
BLSの説明として「C BitがセットかあるいはZ Bitがクリアなら」とあるが、これは「Z Bitがセットなら」の誤り。動作説明は "PC←(PC)+0002+Rel, if (C)⊙(Z)=1" であり、正しい。
参考文献
- M6800 Microprocessor Applications Manual
- MB6881 日立ベーシックマスターレベル2II取扱説明書
- MB6885 ベーシックマスターJr取扱説明書
- 「意外とアヤフヤで使っている人の多い 条件分岐の完全理解」I/O 1981年11月号 P.243
ディスカッション
コメント一覧
まだ、コメントがありません