PICはRISC(reduced instruction set Computer)型のシンプルな命令を高速に実行する方式を採用しています。すべての命令は14bitとなっています。
演算系の命令は、6ビットの命令コード部、1ビットの演算結果を指定する目的部、そして演算の対象となるアドレス部は7bitになっています。命令で直接指定できるメモリは128バイトに限定されます。dは結果を記録する場所を指定し、0のときW、1のときfで指定した番地のレジスタファイルとなります。
0 | 0 | c | c | c | c | d | f | f | f | f | f | f | f |
ビット処理命令は、3ビットのビット部bで、対象番地fのビットを直接操作することができます。これは制御系のコンピュータで多用されるビット処理を意識した命令です。
0 | 1 | c | c | b | b | b | f | f | f | f | f | f | f |
定数命令は、8ビットの定数kを直接指定して演算することができます。
1 | 1 | c | c | c | c | k | k | k | k | k | k | k | k |
ジャンプ命令はコード部3ビット、ジャンプ先を示すアドレスが11ビットです。
1 | 0 | c | a | a | a | a | a | a | a | a | a | a | a |
命令のビット長の制限から、ジャンプ命令ではジャンプの条件が指定できません。そこで、バイト命令にスキップ機能を追加し、条件付ジャンプを実現しました。スキップ機能は、指定した条件が満たされた場合、次の命令をスキップし、「次の次」の命令を実行する機能です。条件が満足されない場合、次の命令を実行します。
スキップ命令を利用すると、繰返しプログラムは次のようになります。
LOOP 繰返し先頭 繰返し 条件付スキップ GOTO LOOP NEXT 繰返し終了
条件付スキップ命令で、条件が満たされないと、次の GOTO LOOP 命令で、LOOP 番地に戻ります。条件が満たされると、GOTO LOOP 命令をスキップするため、繰返しが終了します。
PICでは命令で、直接外部ピンの値を読み込んだり、値の設定ができます。これは SFR(Special Function Register)を利用します。SFR は 0..1F 番地のメモリとして配置されており、
例えば、SFRの PORTB は6H番地に割り付けられており、PORTB 番地を読み書きすることで、RB7..RB0 の8本のポートB端子(ピン RB7..RB0)の値を呼んだり、値を設定できます。
また、 86H番地の TRISB レジスタに値を設定することで、PORTB の端子の入力と出力を設定できます。
RA7 | RA6 | RA5 | RA4 | RA3 | RA2 | RA1 | RA0 |
RB7 | RB6 | RB5 | RB4 | RB3 | RB2 | RB1 | RB0 |
RA7 | RA6 | RA5 | RA4 | RA3 | RA2 | RA1 | RA0 |
RB7 | RB6 | RB5 | RB4 | RB3 | RB2 | RB1 | RB0 |
プログラムで直接指定できる番地は7ビットです。データメモリを増やすためバンク方式を採用し、予め上位の2ビットを指定して128バイト単位のメモリ(これをバンクといいます)を切替えて使用する方法が採用されています。
ジャンプ系で指定できる番地のサイズが2047に限定されます。そこで、命令も2047命令を1バンクとして4バンクを切替えて使用する方式になっています。
ここでは、命令はその機能を示すコード部とその対象を記号で表現します。
MOVLW 0F9H
で、MOVLWが命令の記号、0F9Hは命令で利用されるデータです。こn場合、0F)Hは16進の定数です。この記法をアセンブリ命令(記号命令)といいます。
ここでは、以下の記号を利用します。
c:1バイトの定数
a:11ビットのプログラムメモリの番地
f:7ビットのレジスタファイルの番地
b:ビットを示す定数(0..7)
d:Wまたはfを示す1ビットの定数、演算結果を記録するレジスタを指定します。
演算はW(Working)レジスタが仲介をします。定数系の命令は1バイトの定数cを指定して、Wレジスタへの値を設定したり、Wに定数を演算してWに戻します。
MOVLW c
命令は 定数c をWレジスタに送ります。演算MOVの次のLWが(Literal、Work)を意味します。
ADDLW(SUBLW) はWレジスタにkを加える(減算する)
ANDLW, IORLW, XORLW
は、AND(論理積)、IOR(論理和)、XOR(排他的論理和)を行います。
MOVLW k | 定数kをWに送ります | |
ADDLW k | kにWを加える | |
SUBLW k | kからWを引く | |
ANDLW k | kにWをANDする | |
IOR k | kにWをORする | |
XOR k | kにWをXORする |
例 MOVLW 0F9H ;Wレジスタの値を0F9Hとする
このグループは、主にf(データメモリ)のみを対象に処理を行う命令です。
移動を行う命令は
MOVWF f と、//WをFに
MOVF f,d //fをWに
の2タイプになります。
INCF f 、
DECF f
はfの内容に1を加えたり(INC)減らし(DEC)ます。
CLRF f、
はfの値を0にします(clear)。
CLEW
はWレジスタをクリアします。
COMF f,d
は、fの各ビットを反転(complement)し、結果をWまたはfに返します。
RLF f,d 、RRF f,d
は、fを1ビット左(RLF:Rotate Right)または右(RRF:Rotate Right)に回転し、結果をWまたはfに返します。
fの第bビットを設定する命令があります。fの第bビットを1(BSF)、0(BCF)にします。
BSF f,b
BCF f,b
MOVWF f | Wをfに移動 | |
MOVF f,W | fをWに移動 | Z |
CLRF f | fを0にする | Z |
CLRW | Wを0にする | z |
COMF f,[W|F] | fの2の補数をWまたはfに送る | |
DECF f,[W|F] | fを1減らしWまたはfに送る | Z |
INCF f,[W|F] | fを1増しWまたはfに送る | |
RLF f | fをキャリCを含めて左回転 | C |
RRF f | fをキャリCを含めて右回転 | C |
SWAPF f | fの左右4ビットを入れ替え | |
BSF f,b | fのbビットを1にする | |
BCF f,b | fのbビットを0にする |
WF系の命令は、f番地のメモリとWを演算し結果をWまたはfに返します。
ADDWF f,d
はWにf番地を加え、dが1のときWに、0のときfに結果を返します。fが特殊レジスタ(SFR)を指定する場合、SFRの機能に応じた動作をします。
演算はLW系と同じで、SUBWF,以外に
ANDLW, IORLW, XORLW
が利用できます。
ADDWF f,[W|F] | Wにfを加算し結果をWまたはfに送る | C,DC,Z |
SUBWF f,[W|F] | f からWを引き結果をWまたはfに送る | C,DC,Z |
ANDWF f,[W|F] | fにWをANDし結果をWまたはfに送る | Z |
IORWF f,[W|F] | fにWをORし結果をWまたはfに送る | Z |
XORWF f,[W|F] | fにWをXORし結果をWまたはfに送る | Z |
例 MOVWF CNT1 ;Wの値をレジスタファイルのCNT1に保存する。
ここで、CNT1はレジスタファイルのラベルです。
MOVF VALUE,W ;レジスタファイルのVALUEをWに保存する
計算機は原則として次の番地にある命令を実行します。この実行順序を変更するのが制御系の命令です。
GOTO a
は、次に実行する番地を a に変更します。a は11ビットですから、0〜2047の番地を指定することができます。ただし、GOTO命令は実行の条件を指定できません。条件付でジャンプするには、条件付スキップ機能をもった命令とGOTO命令を組み合わせます。条件付スキップは、指定条件が満たされている場合、次の命令を飛び越して、「次の次」の命令を実行する機能です。スキップする命令がジャンプ命令であれば、ジャンプ命令をスキップできます。
DECFSZ f,F ;fを一つ減らし、0になれば次の命令をスキップ
GOTO LOOP ;LOOPへジャンプ
スキップ機能を持つ命令は他に、して0ならスキップする命令です。
INCFSZ f,d
「指定ビット」の値でスキップする命令があります。
BTFSC f,b
BTFSS f,b
BTFSC は、fの指定ビットが0のとき次の命令をスキップします。また、BTFSSは指定ビットが1のときスキップします。
サブルーティン呼び出しは
CALL a
命令を利用します。これは、C言語の「関数呼び出し」と「戻り」に対応する機能です。CALL a ではa番地を呼び出しますが、このとき、次の番地を戻り番地として「スタック」に記憶しておきます。
サブルーティンからの戻りには
RETURN
命令を利用します。また、
RETLW k
では、定数kをWレジスタに保存して戻る命令です。
戻り番地が保存されるスタックは8レベルですから、連続した呼び出しは8回までに限定されます。
DECFSZ f | fを1減らし、0になったら次の命令をスキップする | |
INCFSZ f | fを1増し、0になったら次の命令をスキップする | |
BTFSC f,b | fのbビットが0なら次の命令をスキップ | |
BTFSS f,b | fのbビットが1なら次の命令をスキップ | |
GOTO a | a番地にジャンプする | |
CALL a | a番地のサブルーチンを呼ぶ | |
RETURN | 戻る | |
RETLW k | 定数をWにセットし戻る | |
RETFIE | 割り込みから戻る | |
CLRWDT | Watch Dog Timer をクリアする | PD,TO |
SLEEP | スリープモードに入る | PD,TO |
NOP | 何もしない(時間調整用) |
こちらに命令一覧表をまとめます。A4 用紙1枚に印刷可能です。
アセンブリ言語は記号言語とも呼ばれます。プログラムを構成する「命令」を、対応する記号で表現したものがアセンブリプログラムになります。
命令の種類を記号で表現します。例えば、定数をワークレジスタに記憶する命令は
MOVLW
と指定します。
特定の番地を記号で代表し、プログラムではその記号で番地を指定します。たとえば、
goto a
命令はa番地にジャンプする命令です。これを
LOOP MOVLW 23h
...
CALL LOOP
次のように、名前に値を設定しておきます。
val EQU 値
EQUは宣言命令または擬似命令と呼ばれ、実行する命令ではありません。
DATA EQU 20h MOVFW DATA
このプログラムは、DATAの値を20hとし、MOVFWのこの値を参照し、20h番地の レジスタファイルの値をWレジスタに移します。記号化することで、DATAの値を変更するとき、EQUの値を変更するだけで、DATAを参照しているすべての命令の値を変更することができます。
#include <ファイル名> ;この位置からファイルの内容を展開します。
ORG 番地 ;プログラムの開始番地を指定します。
END ;プログラムの終了を指定します。
DT <値1>,<値2>,..,<値4> ; RETLW命令で、戻り値を設定します。
DE <値1>,<値2>,..,<値4> ;EEPROMにデータを定義します。
アセンブリプログラムの例を示します。これは30番地から6バイトに0から5の値を順に記憶するプログラムです。
org 0 ;プログラムの先頭 movlw 0x6 movwf count ;count<-6 movlw 0x30 movwf FSR ;メモリ先頭<-30 movlw 0 movwf val NEXT movf val,w movwf INDF ;FSRの番地にWを書き込む incf FSR,f incf val,f decfsz count ;countを減らし goto NEXT ;0でなければNEXTへ戻る loop goto loop ;終了 end