PIC18の標準命令セット

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

標準命令セット

工事中

命令 概要 変化するフラグ サイクル コード
ADDLW k 8bit定数加算 W + k → W C,DC,Z,OV,N 1 0010 01da ffff ffff
ADDWF f , d 加算 W + f → W or f C,DC,Z,OV,N
ADDWFC f , d 加算 W + f +C → W or f C,DC,Z,OV,N
ANDLW k 定数論理積 W AND k → W Z,N
ANDWF f , d 論理積 W AND f → W or f Z,N
BC n キャリーフラグが1の場合ジャンプする
BCF f , b fのbビット目をゼロにクリアする
BN n ネガティブフラグが1の場合ジャンプする
BNC n キャリーフラグが0の場合ジャンプする
BNN n ネガティブビットが0の場合ジャンプする 1(2) 1110 0111 nnnn nnnn
BNOV n オーバーフロービットが0の場合ジャンプする
BNZ n ゼロフラグが0の場合ジャンプする
BOV n オーバーフラグが1の場合ジャンプする
BRA n 無条件で現在のPC+2+2nバイトに相対ジャンプする - 2 1101 0nnn nnnn nnnn
BSF f , b fの b ビット目を1にセットする。
BTFSC f , b fのbビット目がゼロの場合、次命令スキップ
BTFSS f , b fの b ビット目が1の場合、次命令スキップ
BTG f , b ビットを反転させる - 1 0111 bbba ffff ffff
BZ n ゼロフラグが1の場合ジャンプする
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
CLRWDT ウォッチドッグタイマークリア
COMF f , d f の0 , 1反転 → W or f
CPFSEQ W==fの場合、次命令スキップ
CPFSGT f>Wの場合、次命令スキップ
CPFSLT f<Wの場合、次命令スキップ
DAW 10進補正 DC=1の場合または下位4bitが10以上の場合は0x6を加算 上位4bitが10以上の場合は0x60を加算しキャリーを立てる C 1 00000000 0000 0111
DECF f , d f - 1 → W or f C,DC,Z,OV,N
DECFSZ f , d f - 1 → W or f 結果ゼロの場合、次命令スキップ
DCFSNZ f , d f - 1 → W or f 結果ゼロでない場合、次命令スキップ
GOTO k kへジャンプ 2 1110 1111 k7kkk kkkk0
1111 k19kkk kkk8
INCF f , d f + 1 → W or f へ格納 C,DC,Z,OV,N
INCFSZ f , d f + 1 → W or f 結果ゼロの場合、次命令スキップ
ICFSNZ f , d f + 1 → W or f 結果ゼロでない場合、次命令スキップ
IORLW k 定数論理和 W OR k → W Z,N
IORWF f , d 論理和 W OR f → W or f Z,N
LFSR f,k k → FSRf - 2 1110 1110 00ff kkkk
1111 0000 kkkk kkkk
MOVF f , d 移動 f から W or f N Z
MOVFF fs,fd fs → fd
MOVLB k 定数 → BSR - 1 0000 0001 0000 kkkk
MOVLW k 定数k → W -
MOVWF f 移動 W → f Z,N
MULLW k W * k → PRODH:PORDL
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 何もしない
POP リターンスタックをポップ
PUSH PC+2をリターンスタックにプッシュ
RCALL k サブルーチンコール kは相対アドレス(11bit) - 2 1101 1nnn nnnn nnnn
RESET ソフトウェアリセット
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
RLNCF f , d 1ビット左へローテート → W or f キャリーフラグは対象としない。 Z N
RRCF f , d 1ビット右へローテート → W or f C Z N
RRNCF f , d 1ビット右へローテート → W or f キャリーフラグは対象としない。 Z N
SETF fに0ffhを設定する
SLEEP スリープモードにする
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
SUBWF f , d 減算 f - W → W or f N OV C DC Z
SUBWFB f , d 減算 f - W - (inv C) → W or f N OV C DC Z
SWAPF f , d f の上位と下位を入れ替え → W or f
TBLRD* TBLRD*+ TBLRD+* TLBRD*- TLBRD-* TLBPTRレジスタで示されるプログラムメモリから1バイト読み込み結果をTABLATレジスタを上書きします。TLBPTRレジスタは読み込み前または読み込み後に+1または-1または何もしないを設定できます。 TBLRD * ; TLBLAT=*TLBPTR TBLRD *+ ; TLBLAT=*TLBPTR++ TBLRD +* ; TLBLAT=*++TLBPTR TBLRD *- ; TLBLAT=*TLBPTR-- TBLRD -* ; TLBLAT=*--TLBPTR - 2 0000 0000 0000 1000
0000 0000 0000 1001
0000 0000 0000 1010
0000 0000 0000 1011
TBLWT* TBLWT*+ TBLWT+* TLBWT*- TLBWT-* TLBPTRレジスタで示されるTABLATレジスタをプログラムメモリへ上書きします。TLBPTRレジスタは読み込み前または読み込み後に+1または-1または何もしないを設定できます。 TBLWT * ; *TLBPTR=TLBLAT TBLWT *+ ; *TLBPTR++=TLBLAT TBLWT +* ; *++TLBPTR=TLBLAT TBLWT *- ; *TLBPTR--=TLBLAT TBLWT -* ; *--TLBPTR=TLBLAT なし
TSTFSZ f , d ゼロの場合、次命令スキップ - 1(2 or 3) 0110 011a ffff ffff
XORWF f [d,[a]] 排他的論理和 W XOR f → W or f N Z
XORLW k 排他的論理和 W XOR 定数k → W Z,N
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
ADDULNK k FSR2+=k,RETURN
CALLW
MOVSF Zs,fd FSR2+Zs → fd
MOVSS Zs,Zd FSR2+Zs → FSR2+Zd
PUSHL k k → FSR2--
SUBFSR f,k FSR(f)-=k
SUBULNK k FSR2-=k,RETURN
; 拡張命令のテスト
; 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)}