PIC18の標準命令セット

icon 項目のみ表示/展開表示の切り替え

標準命令セット

命令 概要 変化するフラグ サイクル コード
ADDLW k 8bit定数加算 W + k → W C,DC,Z,OV,N 1 0000 1111 kkkk kkkk
ADDWF f,d,a 加算 W + f → W or f C,DC,Z,OV,N 1 0010 01da ffff ffff
ADDWFC f , d 加算 W + f +C → W or f C,DC,Z,OV,N 1 0010 00da ffff ffff
ANDLW k 定数論理積 W AND k → W Z,N 1 0000 1011 kkkk kkkk
ANDWF f , d 論理積 W AND f → W or f Z,N 1 0001 01da ffff ffff
BC n キャリーフラグが1の場合ジャンプする - 1(2) 1110 0010 nnnn nnnn
BCF f , b fのbビット目をゼロにクリアする - 1 1001 bbba ffff ffff
BN n ネガティブフラグが1の場合ジャンプする - 1(2) 1110 0110 nnnn nnnn
BNC n キャリーフラグが0の場合ジャンプする - 1(2) 1110 0011 nnnn nnnn
BNN n ネガティブビットが0の場合ジャンプする - 1(2) 1110 0111 nnnn nnnn
BNOV n オーバーフロービットが0の場合ジャンプする - 1(2) 1110 0101 nnnn nnnn
BNZ n ゼロフラグが0の場合ジャンプする - 1(2) 1110 0001 nnnn nnnn
BOV n オーバーフラグが1の場合ジャンプする - 1(2) 1110 0100 nnnn nnnn
BRA n 無条件で現在のPC+2+2nバイトに相対ジャンプする - 2 1101 0nnn nnnn nnnn
BSF f , b fの b ビット目を1にセットする。 - 1 1000 bbba ffff ffff
BTFSC f , b fのbビット目がゼロの場合、次命令スキップ - 1 1011 bbba ffff ffff
BTFSS f , b fの b ビット目が1の場合、次命令スキップ - 1 1010 bbba ffff ffff
BTG f , b ビットを反転させる - 1 0111 bbba ffff ffff
BZ n ゼロフラグが1の場合ジャンプする - 1(2) 1110 0000 nnnn nnnn
CALL k,s サブルーチン kをコール,S=1の場合、STATUS,BSR,WREGを保存する。CALL k,FASTと記載してもよい。 - 2 1110 110s kkkk kkkk
1111 kkkk kkkk kkkk
CLRF f fをゼロクリア Z 1 0110 101a ffff ffff
CLRWDT ウォッチドッグタイマークリア - 1 0000 0000 0000 0100
COMF f , d f の0 , 1反転 → W or f Z,N 1 0001 11da ffff ffff
CPFSEQ W==fの場合、次命令スキップ - 1(2 or 3) 0110 001a ffff ffff
CPFSGT f>Wの場合、次命令スキップ 1(2 or 3) 0110 010a ffff ffff
CPFSLT f<Wの場合、次命令スキップ 1(2 or 3) 0110 000a ffff ffff
DAW 10進補正 DC=1の場合または下位4bitが10以上の場合は0x6を加算 上位4bitが10以上の場合は0x60を加算しキャリーを立てる C 1 0000 0000 0000 0111
DECF f , d f - 1 → W or f C,DC,Z,OV,N 1 0000 01da ffff ffff
DECFSZ f , d f - 1 → W or f 結果ゼロの場合、次命令スキップ - 1(2 or 3) 0010 11da ffff ffff
DCFSNZ f , d f - 1 → W or f 結果ゼロでない場合、次命令スキップ - 1(2 or 3) 0100 11da ffff ffff
GOTO k kへジャンプ 2 1110 1111 k7kkk kkkk0
1111 kkkk kkkk
INCF f , d f + 1 → W or f へ格納 C,DC,Z,OV,N 1 0010 10da ffff ffff
INCFSZ f , d f + 1 → W or f 結果ゼロの場合、次命令スキップ - 1(2 or 3) 0011 11da ffff ffff
ICFSNZ f , d f + 1 → W or f 結果ゼロでない場合、次命令スキップ - 1(2 or 3) 0100 10da ffff ffff
IORLW k 定数論理和 W OR k → W Z,N 1 0000 1001 kkkk kkkk
IORWF f , d 論理和 W OR f → W or f Z,N 1 0001 00da ffff ffff
LFSR f,k k → FSRf - 2 1110 1110 00ff kkkk
1111 0000 kkkk kkkk
MOVF f , d 移動 f から W or f N Z 1 0101 00da ffff ffff
MOVFF fs,fd fs → fd fs to 1st word
fd to 2nd word
- 2 1100 ffff ffff ffff
1111 ffff ffff ffff
MOVLB k 定数 → BSR - 1 0000 0001 0000 kkkk
MOVLW k 定数k → W - 1 0000 1110 kkkk kkkk
MOVWF f 移動 W → f - 1 0110 111a ffff ffff
MULLW k W * k → PRODH:PORDL - 1 0000 1101 kkkk kkkk
MULWF f,[a] W * f → PRODH:PORDL - 1 0000 001a ffff ffff
NEGF f,[a] 2の補数形式で符号を反転 N OV C DC Z 1 0110 110a ffff ffff
NOP 何もしない - 1 0000 0000 0000 0000
POP リターンスタックをポップ - 1 0000 0000 0000 0110
PUSH PC+2をリターンスタックにプッシュ - 1 0000 0000 0000 0101
RCALL k サブルーチンコール kは相対アドレス(11bit) - 2 1101 1nnn nnnn nnnn
RESET ソフトウェアリセット - 2 0000 0000 1111 1111
RETFIE s 割り込みから復帰。s=1の場合、WREG,BSR,SATUSSを復帰 RETFIE FASTと記述してもよい GIE/GIEH,PEIE,GIEL 2 0000 0000 0001 000s
RETLW k W に k を格納して戻る - 2 0000 1100 kkkk kkkk
RETURN サブルーチンから戻る - 2 0000 0000 0001 001s
RLCF f , d 1ビット左へローテート → W or f 最下位にはキャリーフラグの内容が上書きされる。 シフトであふれた最上位ビットはキャリーフラグに上書きされる C N Z 1 0011 01da ffff ffff
RLNCF f , d 1ビット左へローテート → W or f キャリーフラグは対象としない。 Z N 1 0100 01da ffff ffff
RRCF f , d 1ビット右へローテート → W or f C Z N 1 0011 00da ffff ffff
RRNCF f , d 1ビット右へローテート → W or f キャリーフラグは対象としない。 Z N 1 0100 00da ffff ffff
SETF fに0ffhを設定する - 1 0110 100a ffff ffff
SLEEP スリープモードにする - 1 0000 0000 0000 0011
SUBFWB f , d 減算 W - F- (inv C) → W or f N OV C DC Z 1 0101 01da ffff ffff
SUBLW k 定数k - W → W N OV C DC Z 1 0000 1000 kkkk kkkk
SUBWF f , d 減算 f - W → W or f N OV C DC Z 1 0101 11da ffff ffff
SUBWFB f , d 減算 f - W - (inv C) → W or f N OV C DC Z 1 0101 10da ffff ffff
SWAPF f , d f の上位と下位を入れ替え → W or f - 1 0011 10da ffff ffff
TBLRD* TBLRD*+ TBLRD+* TLBRD*- TLBPTRレジスタで示されるプログラムメモリから1バイト読み込み結果をTABLATレジスタを上書きします。 TLBPTRレジスタは読み込み前または読み込み後に+1または-1または何もしないを設定できます。 - 2 0000 0000 0000 1000

0000 0000 0000 1001

0000 0000 0000 1010

0000 0000 0000 1011
TBLWT* TBLWT*+ TLBWT*- TBLWT +* TLBPTRレジスタで示されるTABLATレジスタをプログラムメモリへ上書きします。TLBPTRレジスタは読み込み前または読み込み後に+1または-1または何もしないを設定できます。 - 2 0000 0000 0000 1100

0000 0000 0000 1101

0000 0000 0000 1110

0000 0000 0000 1111
TSTFSZ f , d ゼロの場合、次命令スキップ - 1(2 or 3) 0110 011a ffff ffff
XORWF f [d,[a]] 排他的論理和 W XOR f → W or f N Z 1 0001 10da ffff ffff
XORLW k 排他的論理和 W XOR 定数k → W Z,N 1 0000 1010 kkkk kkkk
W:ワーキングレジスタ F:レジスタファイル
d=0の時、Wレジスタが対象
d=1の時、fレジスタが対象 省略時の規定値
a=0の時、アクセスバンクを選択(省略時) ACCESSと記述してもよい。
a=1の時、バンクセレクトレジスタ(BSR) BANKEDと記述してもよい。
FSR(f)
INDF(f)     (FSR(f))
POSTDEC(f) (FSR(f)--)
POSTNC(f) (FSR(f)++)
PREINC(f) (++FSR(f))
PLUSW     (FSR(f)+WREG)
WREGは符号付8bit
リードモディファイタイプの命令の場合、読み書きが終了してからポインタの操作が実行されます。

拡張命令

拡張命令を有効にするとFSR2相対アドレッシングやFSR2に対する加算や減算等を行う命令が使用できます。
アクセスバンクによるアクセスがFSR2相対アドレスに変更されます。
具体的にはアクセスバンクによるアドレスが0x60未満の場合はFSR2相対、0x60以上の場合はバンクが0xfとしてアクセスされます。
命令 概要 変化するフラグ サイクル コード
ADDFSR f,k FSR(f)+=k - 1 1110 1000 ffff kkkk
ADDULNK k FSR2+=k,RETURN - 1 1110 1000 11kk kkkk
CALLW call WREG - 2 1110 1000 11kk kkkk
MOVSF Zs,fd FSR2+Zs → fd - 2 1110 1011 0zzz zzz
1111 ffff ffff ffff
MOVSS Zs,Zd FSR2+Zs → FSR2+Zd - 2 1110 1011 1zzz zzzz
1111 xxxx xzzz zzzz
PUSHL k k → FSR2-- - 1 1110 1010 kkkk kkkk
SUBFSR f,k FSR(f)-=k - 1 1110 1001 ffkk kkkk
SUBULNK k FSR2-=k,RETURN - 2 1110 1001 11kk kkkk
; 拡張命令のテスト
; FSR2相対アドレスで書き込みバンクで読み込みする
; MPLAB X IDE v3.45 Microchip MPASM(v5.70)

        #INCLUDE <p18f46k22.inc>
        ; 水晶発振(16MHz) クロック分周無 PLL有効(*4) プライマリクロック有効  ウォッチドッグタイマ無効 低電圧プログラム書き込みモード無効
        CONFIG FOSC = HSHP,PLLCFG=ON,PRICLKEN=ON,WDTEN=OFF,LVP=OFF,XINST=ON

bank0    UDATA  ; 変数の定義
buf      RES    2

        CODE
        ORG 0
        goto   start    ;   リセット時
start
        lfsr    2,buf   ;bufのアドレスをFSR2にロード
        movlw   0aah
        movwf   [1] ;   FSR2+1のアドレスに書き込み
        clrf    WREG
        banksel buf
        movf    buf+1,w,BANKED  ;   バンクでアクセス
        bra     $

        END

ステータスレジスタ

7 6 5 4 3 2 1 0
N OV Z DC C
C:キャリー 加算の場合、桁上げが生じた場合1がセットされる。減算の場合、桁借りが生じた場合0がセットされる。
N:ネガティブ 命令の実行結果が7bit目が反映される
Z:ゼロ 命令の実行結果が0の場合1がセットされる
OV:7ビット越えのオーバーフローフラグ
DC:下位4bitのキャリ(DAW命令で参照される)
  127+129=256 
  0111 1111 0x7f 127
 +1000 0001 0x81  129
------------
  0000 0000 0x00
1 0000 0000      n ov Z DC C

64+65=129 
  0100 0000
 +0100 0001
------------
  1000 0001 0x81
0 1000 0001      N OV z dc c 


-64+-65=127 -129
  1100 0000 0xc0 -64
 +1011 1111 0xbf -65
-----------
  1111 1111 0xff
1 0111 1111      n OV z dc C

BCD演算の例
;16+24=40
;16    0x16
;24    0x24
MOVLW 0x16
ADDLW 0x24  ; 0x40→W  n ov z dc c
DAW  ; 0x40→W
;18+28=46
;0x18+0x28
MOVLW 0x18
ADDLW 0x28  ; 0x40→W  n ov z DC c
DAW         ; 0x46→W  n ov z DC c

定数の記述

ディフォルトが16進数であることに注意が必要です。
MOVLW b'11000110'       ;2進数
MOVLW A'j'      ;       文字定数
MOVLW d'100' ; 10進数
MOVLW 10 ; 16進数(10進数では16になる)
MOVLW 0x10' ; 16進数
MOVLW H'10' ; 16進数

変数の確保

アクセスバンク(0000h~005fh)

UDATA_ACS

番地指定

特定のバンクに割り当てるなど番地を指定する場合に使用します。例えばバンク1に割り当てる場合は以下の様に記述します。 IDATA 0100h

リロケータブル

UDATA
BANKEDはマクロで定義されている。

符号付ビットシフト

掛け算や割り算を高速に実行する方法としてビットシフトを使用しますが、符号付の値を普通にシフトする値がおかしくなります。と命令はPIC18には存在しません。8086では算術シフト(SAR SAL命令)と呼びます。単純なシフトは論理シフトと呼びます。
例えば右ローテートで符号付で/2を算出するにはあらかじめ最上位ビットの値をキャリーフラグにコピーしておき右ローテートを実行します。
右シフトを複数バイトにわたって実行する場合は、上位ビットに対して算術シフトを行い、あとはキャリーフラグ付きの右シフトを実行すれば可能です。
-4 --> (not 4) +1)=b'00000100' b'11111011' +1 b'11111100' /2 ---> b'11111110'
算術右シフト
        bcf     STATUS,C
        btfsc   WREG,7
        bsf     STATUS,C
        rrcf    WREG
算術左シフト
;  7bit目をDCフラグにコピー
        bcf     STATUS,DC
        btfsc   WREG,7
        bsf     STATUS,DC
        rlcf    WREG
        rlcf    WREG
;   DCフラグをCフラグにコピー
        bcf     STATUS,C
        btfsc   STATUS,DC
        bsf     STATUS,C
        rrcf    WREG

16bitのインクリメント

3サイクル
incf    DTC
btfsc   STATUS,C
incf    DTC+1

16bitのデクリメント

3サイクル 減算の場合はキャリーフラグが0で桁借りを示してます。
decf    DTC
btfss   STATUS,C
decf    DTC+1

16bit同士の減算

        movf    SRC,W
        subwf   DTC ;   DTC-SRC
        movf    SRC+1,W
        subwfb  DTC+1   ;   DTC1-SRC1
        
        234-1234=-1000    64536(0FC18h) 
        Nフラグで大小がわかる N=1  src>dtc
        イコールはZフラグではわからない(上位と桁借りのみ繁栄されるため 下位がわからない N=0 Z=1 下位同士が0であればイコール)

16bitの2の補数

2の補数とは全ビットを反転させ1を足したものです。
1byteの場合はNEGF命令が使用できます。
2byteの場合は、
comf    DTC
comf    DTC+1
incf    DTC
btfsc   STATUS,C
incf    DTC+1
NEGF命令は結果に桁上げが発生した場合はCフラグがセットされるので以下のようにも記述できる。
comf    DTC+1
negf    DTC
btfsc   STATUS,C
incf    DTC+1

16bit同士の比較

16bit同士の減算をし大小の比較をします。上位の答えが0の場合、桁借りも含めて0になったか不明なので下位の減算結果が0であればイコールと判断しています。 フラグの立ち方が8bitのsub系の命令と同じになりますので応用が楽かと思います。 Z=1 src==dtc N=1 src>dtc N=0 dtc>src
        movf    SRC,W
        subwf   DTC ;   DTC-SRC
        movf    SRC+1,W
        subwfb  DTC+1   ;   DTC1-SRC1
        btfss   STATUS,Z
        bra     CMP16HNZ
        bcf     STATUS,Z
        tstfsz  DTC
        bra     CMP16HNZ
        bsf     STATUS,Z
CMP16HNZ
        bz      JE16    ; src==dtc
        bn      JL16    ; src>dtc
        bra     JG16    ; dtc>src
        
        movf    SRC,W
        subwf   DTC ;   DTC-SRC
        movf    SRC+1,W
        subwfb  DTC+1   ;   DTC1-SRC1
        btfss   STATUS,Z
        bra     $+6
        bcf     STATUS,Z
        tstfsz  DTC
        bra     $+2
        bsf     STATUS,Z

        movf    STATUS,W
        andlw   1<<N | 1<<Z ; 0B14   00010100
        bnz     JLE 
        movlw   d'1'

パリティ

        movwf   POSTDEC2
        swapf   WREG
        xorwf   PREINC2,W
        movwf   POSTDEC2
        rrcf    WREG
        xorwf   PREINC2,W
        movwf   POSTDEC2
        rrcf    WREG
        rrcf    WREG
        xorwf   PREINC2,W
        rrcf    WREG
A
7 6 5 4 3 2 1 0
WREG A7 A6 A5 A4 A3 A2 A1 A0
B=上位と下位を交換
7 6 5 4 3 2 1 0
swap A3 A2 A1 A0 A7 A6 A5 A4
C=A ^ B
7 6 5 4 3 2 1 0
xor A7^A3 A6^A2 A5^A1 A4^A0 A3^A7 A2^A6 A1^A5 A0^A4
D=C>>1
7 6 5 4 3 2 1 0
rrf C' A7^A3 A6^A2 A5^A1 A4^A0 A3^A7 A2^A6 A1^A5
E=C ^ D
7 6 5 4 3 2 1 0
XOR (A7^A3)^C' (A6^A2)^(A7^A3) (A5^A1)^(A6^A2) (A4^A0)^(A5^A1) (A3^A7)^(A4^A0) (A2^A6)^(A3^A7) (A1^A5)^(A2^A6) (A0^A4)^(A1^A5)
F=E>>2
7 6 5 4 3 2 1 0
rrf A1^A5 (A7^A3)^C' (A6^A2)^(A7^A3) (A5^A1)^(A6^A2) (A4^A0)^(A5^A1) (A3^A7)^(A4^A0) (A2^A6)^(A3^A7) (A1^A5)^(A2^A6)
G=E ^ F
7 6 5 4 3 2 1 0
XOR {(A7^A3)^C'}^{(A1^A5)^(A2^A6)} {(A6^A2)^(A7^A3)}^{A1^A5} {(A5^A1)^(A6^A2)}^{(A7^A3)^C'} {(A4^A0)^(A5^A1)}^{(A6^A2)^(A7^A3)} {(A3^A7)^(A4^A0)}^{(A5^A1)^(A6^A2)} {(A2^A6)^(A3^A7)}^{(A4^A0)^(A5^A1)} {(A1^A5)^(A2^A6)}^{(A3^A7)^(A4^A0)} {(A0^A4)^(A1^A5)}^{(A2^A6)^(A3^A7)}