指定したレジスタの値を+1、−1する命令で、INCF f,d、DECF f,d命令が
これに属します。いずれも構造は図2(a)の形です。
nemonic : 内容 :Flag :Cycle :オペコード
----------------------------------------------------------
DECF f,d : f - 1 ->dest : Z : 1 : 00 0011 dfff ffff
INCF f,d : f + 1 ->dest : Z : 1 : 00 1010 dfff ffff
【カウントアップダウン命令の動作】
(1)命令フェッチ
プログラムカウンタの指し示すアドレスの命令が、プログラムメモリから
命令レジスタに呼び出されます。
(2)命令解読実行
INCF、DECFが命令レジスタに行くと、そこで命令コードが解読されます。
(3)レジスタデータの取り出し
命令中の f で指定されたレジスタファイルのアドレス fで指定された
f レジスタが、ALUの右側にデータバスを経由して呼び出されます。
(4)カウントアップダウンの実行
fレジスタの内容は、ALUの中で+1、−1されて出力されます。出力結果
は、 d の値により、Wregかfレジスタに上書きされます。
(5)STATUS
結果の状態もゼロフラグだけが影響を受け、STATUSレジスタに書き込
まれます。
【カウント命令の使い方】
単純なカウントアップ、ダウン
INCF DATA,F ;DATAの内容を+1する
DECF DATA,W ;DATAの内容−1をWregへ
;DATAの内容は変化しない
INCFSZ f,d、DECFSZ f,d命令がこれに属します。構造は図2(a)で同じです。
nemonic : 内容 :Flag :Cycle :オペコード
----------------------------------------------------------------
DECFSZ f,d : f - 1 -> dest, : None : 1(2) : 00 1011 dfff ffff
skip if result=0
INCFSZ f,d : f + 1 -> dest, : None : 1(2) : 00 1111 dfff ffff
skip if result=0
【命令の動作】
INCFSZ、DECFSZは、演算動作はそれぞれINCFとDECFと同じなのですが、
カウント結果がゼロになった時だけ、次ぎの命令をNOP命令に強制的に
置き換えてしまう動作をします。
そうすると、NOP命令は動作としては何もせずプログラムカウンタだけが+1
されることになってしまいます。
つまり、次ぎの命令を実行せず、次ぎの次ぎの命令に移ってしまうことになり、
スキップしたことになります。
【カウント命令の使い方】
(1)繰り返し処理(FOR文)の作り方
PICでいわゆるFOR文に相当するプログラムはどう作れば良いのでしょうか?
FOR文にはカウンタとなる変数を用意して、これとDECFSZ命令を組み合わ
せて作ります。
下記のような構造でループさせます。
MOVLW 10 ;10回繰り返す(FOR文のiに相当)
MOVWF i ;iの初期セット
LOOP
|
(この間に繰り返す処理を入れる)
|
DECFSZ i,F ;カウンタ−1&チェック
GOTO LOOP ;繰り返しループ
次ぎの処理へ
(注:変数 i は最初の方で変数定義をしておくこと)