まとめておこうかなー。と。
何が混乱するかってキャリーフラグです。
Z80ではJZとかJGとかJLとか命令が覚えやすかったからいいんですが、PICはBTFSC STATUS, Cとかキャリーフラグがどうなるか把握してないと書けないような命令しかないので…。
なので把握しとけって事ですね、分かります。
最大のミソは、減算命令が減算するというよりWレジスタの2の補数を加算する命令だってことですよね。
(他のCPUも同じですが、なんというかPICはモロにそのまんまというイメージ)
というわけでまとめを書いてみますが…書くのが楽なのでSUBLWで。
SUBLW k
Wの2の補数にkを加算してWに格納する
W=(-W)+k=k-W (W-k じゃないよ)
影響フラグ:
C:桁あふれが発生したら立つ
DC:下位4ビットから桁あふれが発生すると立つ(←使った試しがない)
Z:計算結果が0だと立つ
例:
W=1, k=3 の場合 (3-1)
Wの2の補数=255
k+255=258 (0x102)
桁あふれが発生して結果は2になるので
W=2, C=1, Z=0
W=3, f=1 の場合 (1-3)
Wの2の補数=253
f+253=254 (0xfe, -2)
桁あふれは発生していないので
W=254(-2), C=0, Z=0
W=2, f=2 の場合 (2-2)
Wの2の補数=254
f+254=256 (0x100, 0)
桁あふれが発生するので
W=0, C=1, Z=1
というわけで…。
引き算だと考えると一見ボローが発生していない状況でCフラグが立つ。
というのがわかりにくいんだよー。
SUBWF もリテラルがFに置き換わるだけで同じ。
よく使うのは、やっぱりFレジスタの内容を加算していって、それがある一定の値を超えたかどうかの判定でしょうか。
CLRF COUNTER
LOOP1
MOVLW 30
SUBWF COUNTER, W
BTFSC STATUS, C
GOTO EXIT
INCF COUNTER, F
GOTO LOOP1
EXIT
たとえばこんなやつですね。
4行目のSUBWFではカウンタ値から30を引くわけです。
カウンタ値が小さいうちはボローが発生するのでCフラグが立ちません。(ここが感覚的に逆)
カウンタ値が30になるとZフラグとCフラグが立ちます。
ので、ラベルEXITへジャンプします。
引き算の結果がマイナスになるときだけはキャリーフラグがクリアになる
ってことでいいのかな。うん。それが一番覚え易いw
私はほとんどPICしか触らないので苦にならないのですが、減算時のキャリーフラグの挙動が気になる方も多いようですね。
擬似命令のMACROを使ってしまうのも1つの手だと思います。例えばボロー(キャリーの反転)が立つときだけ次の命令をスキップするならこんな感じです。
SKIPB MACRO
BTFSC STATUS,C
ENDM
MACROの定義はインクルードファイルにまとめてしまえば、使い回しが楽です。