PICの演算命令の使い方

A.加減算命令

【加減算命令の種類】

もっとも基本的な演算である足し算と引き算の命令です。
下記命令がこれに対応します。

nemonic   : 内容      : Flag  :Cycle :命令コード
-----------------------------------------------------------------
ADDWF f,d : w + f -> dest  : C,DC,Z : 1  : 00 0111 dfff ffff
SUBWF f,d : f - w -> dest  : C,CD,Z : 1  : 00 0010 dfff ffff
ADDLW k  : w + k -> w   : C,DC,Z : 1  : 11 111x kkkk kkkk
SUBLW k  : k - w -> w   : C,CD,Z : 1  : 11 110x kkkk kkkk




【加減算命令の動作】

PICの内部構成図である図1で、これらの命令の動作を説明して行きます。
まず、ADDWFとSUBWF命令の動作です。

(1)命令の取りだし(フェッチするという)
 ADDWF、SUBWF命令は、命令の中身は上図(a)の様になっています。
 まず現在のプログラムカウンタが指しているアドレスの命令が、プロ
 グラムメモリから呼び出されて命令レジスタに行きます。
(2)命令の解読
 命令レジスタで命令コードが解読され演算関連の命令だと判定され
 ます。
(3)データの取り出し
 命令構造の中にある f で指定されるレジスタファイルの f 番地の内容
 (fレジスタと呼ぶ)が、Mux経由ALUの右側に行きます。
 また、現在のWregにある内容がALUの左側に呼び出されます。
(4)演算の実行と結果の保存
 呼び出されたデータは、ALU内で加算(減算)され、結果がALUの出力
 側に現れます。 この結果データは 、命令構造の中の、dが0なら
 Wregに上書きされ、dが1なら、fレジスタにデータバス経由で上書き
 されます。
 この時の減算の方向は、f−Wregとなります。
(5)状態の保存
 さらに結果の状態がSTATUSレジスタに書き込まれます。





【リテラル加減算命令の動作】

次ぎに、リテラル命令であるADDLW、SUBLW命令の中身は構造図(c)の
 様になっています。
 この場合の動作をやはりPIC構成図で示すと、図3のようになります。
 
(6)命令フェッチ
  命令がプログラムメモリから呼び出されて命令レジスタに行き解読され
  ます。
(7)リテラルの取りだし
  命令の中にある、kのデータがMux経由ALUの右側に行きます。
  さらに現在のWregの内容がALUの左側へ行って加算(減算)されます。
(8)結果の格納
  結果は Wregに上書きされます。 この時の減算の方向は、k−Wregです。
(9)状態の格納
 STATUSの条件はADDWFと同じ動作です。






【加減算命令の使い方】

実際の加減算命令の使い方は下記の様にします。
まずWregに引数を取りだし、その後レジスタを加減算します。
この時注意が必要なことは、引き算の向きです。

例)単純な1バイトデータの演算例

(1)A+B
   MOVF   A,W  ;実行前 A=0x17 B=0xC2 Wreg=xx
   ADDWF  B,W  ;実行後 A=0x17 B=0xC2 Wreg=0xD9 C=0

(2)B-A
   MOVF   A,W  ;実行前 A=0x17 B=0xC2 Wreg=xx
   SUBWF  B,W  ;実行後 A=0x17 B=0xC2 Wreg=0xAB C=1

  (注)引き算の向きは、B-Aで、Carryフラグも正の時が「1」です。


B.論理演算命令

【論理演算命令の種類と動作】

論理演算をする命令で、ANDWF f,d、ANDLW k、IORWF f,d、IORLW k、
XORWF f,d、XORLW k、COMF f,d がこれに属します。

nemonic   : 内容       :Flag :Cycle :命令コード
---------------------------------------------------------------
ANDLW k  : w AND k -> w   : Z  : 1  : 11 1001 kkkk kkkk
ANDWF f,d : w AND f -> dest  : Z  : 1  : 00 0101 dfff ffff
IORLW k  : w OR k -> w    : Z  : 1  : 11 1000 kkkk kkkk
IORWF f,d : w OR f -> dest  : Z  : 1  : 00 0100 dfff ffff
XORLW k  : w XOR k -> w   : Z  : 1  : 11 1010 kkkk kkkk
XORWF f,d : w XOR f -> dest  : Z  : 1  : 00 0110 dfff ffff

COMF f,d  : f -> dest     : Z  : 1  : 00 1001 dfff ffff



動作は前の加減算命令と全く同じで、ALU内部での演算の仕方が異なる
だけです。

 ANDWFとANDLWは、Wregとfレジスタまたは定数kとのANDを取ります。
つまり、各ビット毎にいずれかが0なら0、両方とも1の時だけ1となります。

 IORWFとIORLWは、Wregとfレジスタまたは定数kとのORを取ります。
つまり、各ビット毎に、いずれかが1だったら1、両方とも0だったら0とします。

 XORWFとXORLWは、Wregとfレジスタまたは定数kとの排他論理和を取り
ます。
つまり、両レジスタの各ビット毎に、同じなら0、異なっていれば1とします。

 COMFはfレジスタの補数演算、つまり1,0を反転します。実際の演算は
FF−fを実行しています。

またこれらの命令の実行結果のSTATUSは、ゼロフラグのみが反映されます。



【論理演算命令の使い方】

論理演算命令の実際の使い方は下記の様にします。

例)単純な1バイトデータの演算例

(1)A AND B
   MOVF   A,W  ;実行前 A=0x17 B=0xC2 Wreg=xx
   ANDWF  B,W  ;実行後 A=0x17 B=0xC2 Wreg=0x02 C=x

        0001 0111 (0x17)
        1100 0010 (0xC2)
      AND 0000 0010 (0x02)

(2)A XOR 0xAF(リテラル)
   MOVF   A,W  ;実行前 A=0xB5 Wreg=xx
   XORLW  0xAF  ;実行後 A=0xB5 Wreg=0x1A C=x
  
        1011 0101 (0xB5)
        1010 1111 (0xAF)
     XOR  0001 1010 (0x1A)

            


   次のページへ      目次ページへ