MC6800のプログラミングテクニック(9) シフト・ローテート命令のVフラグ
NEG命令が意外に使える命令だとわかったので、他にも特殊なフラグ変化をする命令がないか探してみた。あった。
シフト・ローテート命令群のVフラグの変化に特記事項⑥がついている。
M6800 Microprocessor Applications Manual, Motorola 19751-18 より引用
⑥の解説には以下のように書かれている。シフト後のNとCの排他的論理和になるらしい。
⑥ (Bit V) Test: Set equal to result of N ⊕ C after shift has occurred.
ベーシックマスター L2II / Jr. のマニュアルでも同様。
もし、操作の結果、“NがセットでCがクリア” かあるいは “NがクリアでCがセット” ならばセット、さもなくばクリア
BASIC MASTER MB6881 ベーシックマスター レベル2II 取扱説明書, HITACHI P.123 より引用
MC6809のマニュアルではどうなっているか
記述が異なっている部分がある。例えば、ASR命令では、Vは Not affectedである。
R – Not affected
MC6809-MC6809E 8-Bit Microprocessor Programming Manual (Motorola Inc.) 1981 A-10より引用
一覧にしてみた。右移動がNot Affected、左移動の場合は、命令実行前のb7とb6のxorになる。
左移動では、b7がCに、b6がb7に移動するので、移動後のCとb7(N)とのxorでもある。結局は、モトローラ1975やベーシックマスター取扱説明書と同じことを明快に書いているだけだ。
他の文献も調べてみたが、右移動でのフラグ変化は非互換のようだ。
命令 | Vフラグ変化 |
---|---|
ASL/LSL | Loaded with the result of the exclusive OR of bits six and seven of the original operand |
ASR | Not affected |
LSR | Not affected |
ROL | Loaded with the result of the exclusive OR of bits six and seven of the original operand. |
ROR | Not affected |
困った時はvisual 6800
念の為、6800でのフラグ変化をVisual 6800を使って確認してみた。Visual 6800はトランジスタレベルでシミュレートしてくれる優れもののシミュレーターだ。
確認方法
下記のような短いコードを書いて、値を変えながら確認してみた。
LDAA #$80 LSLA
全命令でモトローラのマニュアル通り、N⊕C になっていた。
他のエミュレーターには、右シフトでは6809同様にVを変化させないものがあった。困る。
Vフラグの変化は何に使えるか?
あまり使い道を思いつかないのだけど、無理やり考えたのが、AccA,Bが同符号であるかの判定。
以下の3命令で同符号ならV=0, 異符号ならV=1になる。Bは破壊されない。Aも壊したくなければ、ASLAの代わりにASRA/ROLA。
RORB/ROLB は ROLB/RORB でも良い。
ASLA RORB ROLB
通常はEORを使うのだけど、レジスタ間EOR命令はないので、メモリへの退避が発生する。Bを破壊したくなければ、PSHB/PULBが必要。
STAA @tmp EORB @tmp
右シフト(ASR/LSR)はb7がセット/リセットされるので、結局元のb0の値が!V/Vになるだけである。この用途はCで間に合う。
右ローテートの場合は、元のCとb0のxorになるのだが、こちらは用途を思いつかない。
ASRA/RORBでレジスタ間でのb0同士の排他的論理和が計算できるのだけど、それはABA/ANDA #1 やABA/ASRAで良い。非互換問題も発生しない。
追記
左シフト・ローテートだと、元々のb7とb6の xor を検出できる。
2進数で 00000000〜00111111の範囲と、11000000〜11111111の範囲はV=0、それ以外がV=1である。
10進だと0〜63、-64〜-1 の範囲であり、ある1バイトの数値が -64〜63 の範囲であるかを1命令で検出できる。できるけど使い道あるかなあ…
ディスカッション
コメント一覧
まだ、コメントがありません