PAアセンブラにはオリジナルのPICマイコンの命令以外にこのアセンブラ独自の拡張命令があります。
拡張といってもPICマイコンの命令の他に新たに命令が作れるという訳ではなく下記の命令を使用した場合、
主に複数の命令に展開されてコーディングができるという考え方です。
これで数値の比較や他のページへのコールなどが容易に行えるなどのメリットがあります。しかし、
他のアセンブラでは使用できないとか他のプログラマが理解できないというデメリットもあります。
add fr,#lite | C,Z,DC |
ファイルレジスタfrと定数liteを加算して結果をfrに戻します。
実行クロックは2サイクルです。
演算結果に応じてC,Z,DCフラグが変化します。
|
add fr1,fr2 |
ファイルレジスタfr1とfr2を加算して結果をfr1に戻します。
実行クロックは2サイクルです。
演算結果に応じてC,Z,DCフラグが変化します。
|
add fr,W |
ファイルレジスタfrとWを加算して結果をfrに戻します。
実行クロックは1サイクルです。
演算結果に応じてC,Z,DCフラグが変化します。
|
add W,fr |
ファイルレジスタfrとWを加算して結果をWに戻します。
実行クロックは1サイクルです。
演算結果に応じてC,Z,DCフラグが変化します。
|
addb fr,bit |
bitで指定したビットが1のときファイルレジスタfrに1を加算します。
0の時は何もしません。実行クロックは2サイクルです。
フラグは変化しません。
|
and fr,#lite |
|
and fr1,fr2 |
|
and fr,W |
|
and W,#lite |
|
and W,fr |
|
cja fr,#lite,addr9 |
(Compare Jump Above)
ファイルレジスタと定数を比較して条件が真ならジャンプします。
fr > liteの時ラベルで指定したアドレスにジャンプします。
|
cja fr1,fr2,addr9 |
(Compare Jump Above)
ファイルレジスタと定数を比較して条件が真ならジャンプします。
fr1 > fr2の時ラベルで指定したアドレスにジャンプします。
|
cjae fr,#lite,addr9 |
ファイルレジスタと定数を比較して条件が真ならジャンプします。
fr >= liteの時ラベルで指定したアドレスにジャンプします。
|
cjae fr1,fr2,addr9 |
|
cjb fr,#lite,addr9 |
|
cjb fr1,fr2,addr9 |
|
cjbe fr,#lite,addr9 |
|
cjbe fr1,fr2,addr9 |
|
cje fr,#lite,addr9 |
|
cje fr1,fr2,addr9 |
|
cjne fr,#lite,addr9 |
|
cjne fr1,fr2,addr9 |
|
clc |
|
clr fr |
ファイルレジスタfrを0にクリアします。
Zフラグが1にセットされます。実行クロックは1サイクルです。
|
clr w |
Wレジスタをクリアします。それだけです。
Zフラグが1にセットされます。
|
clr wdt |
|
clrb bit |
|
clz |
|
csa fr,#lite |
|
csa fr1,fr2 |
|
csae fr,#lite |
|
csae fr1,fr2 |
|
csb fr,#lite |
|
csb fr1,fr2 |
|
csbe fr,#lite |
|
csbe fr1,fr2 |
|
cse fr,#lite |
|
cse fr1,fr2 |
|
csne fr,#lite |
|
csne fr1,fr2 |
|
dec fr |
|
decsz fr |
|
djnz fr,addr9 |
ファイルレジスタfrから1を減算して、結果が0以外のとき、ラベルaddr9で示される
アドレスにジャンプします。上記以外のときは次の命令に移ります。
この命令は、プログラム中のループ(for..nextに相当)によく使用されます。
たとえば100回のループを組む場合はこのようにします。
;****************************************
org 10h
cn ds 1
org 0
test mov cn,#100 ; 変数に初期値100を代入します。
loop1 nop ; この命令を100回実行します。
djnz cn,loop1
;****************************************
この命令を使うことで、プログラムがすっきりし、見やすくなります。
上記のプログラムのcnに好きな値を入れればその回数分ループを繰り返す訳です。
cnは8ビットですから0〜255までの値がとれますが、0を入れた場合はループは
256回繰り返されますので、注意してください。
|
ijnz fr,addr9 |
ファイルレジスタfrに1を加算して、結果が0以外のとき、ラベルaddr9で示される
アドレスにジャンプします。上記以外のときは次の命令に移ります。
この命令はdjnz命令と反対に1を加算して、結果によってジャンプする命令ですが、
通常この命令を使うとややこしくなるので普通は使いません。djnzと対象的に設けられた
命令です。
|
inc fr |
ファイルレジスタfrに1を加算します。frがFFhの時に1を加算したときは
結果が0になります。実行クロック数は1サイクルです。
注意:この命令によってフラグ(ステータスレジスタフラグ)は変化しません。
フラグを変化させるには、
add fr,#1
と、コーディングしてください。(実行クロックは2サイクルとなります)
|
incsz fr |
|
jb bit,addr9 |
|
jc addr9 |
|
jmp addr9 |
ラベルaddr9で示されるアドレスに無条件ジャンプする命令です。
|
jmp pc+w |
PCの値にWレジスタの値を加算して、Wレジスタの値に応じてプログラムを分岐
させることができます。
この命令は配列テーブルや文字列テーブルから
|
jmp w |
|
jnb bit,addr9 |
|
jnc addr9 |
|
jnz addr9 |
|
jz addr9 |
|
lcall addr11 |
この命令はPIC16C5X専用に用意されています。
16C5Xではcall命令で指定できるアドレスは、アドレスの下位8ビットだけで
call命令を実行すると、A0〜7は命令からセットされ、A8は0(固定)にセット、
A9,10はステータスレジスタのPA0,1が暗黙のうちに移動されます。
(こういう、アーキテクチャはプログラムしにくいので止めてほしい>マイクロチップ)
A8が0に固定なので、一部コール不能な領域があります。このせいでサブルーチンの
書き方にコツがいります。
上位ビットのPA0,1をプログラマが管理していないとどっか違うバンクのサブルーチンに
飛んでいってしまいします。これが面倒なので、この命令を用意しました。
この命令は始めにPA0,1のビットをコールするアドレスに合わせて自動的に
セットして、その後call命令を生成します。これで、上位ビットを気にせず
サブルーチンコールできます。
A8が1のアドレスに飛ぼうとすると、アセンブルエラーになります。
この命令と併用してlset命令も必ず使用するはずです。そちらも参照してください。
|
ljmp addr11 |
この命令はPIC16C5X専用に用意されています。
16C5Xではcall命令で指定できるアドレスは、アドレスの下位9ビットだけで
call命令を実行すると、A0〜8は命令からセットされ、
A9,10はステータスレジスタのPA0,1が暗黙のうちに移動されます。
(こういう、アーキテクチャはプログラムしにくいので止めてほしい>マイクロチップ)
上位ビットのPA0,1をプログラマが管理していないとどっか違うバンクのサブルーチンに
飛んでいってしまいします。これが面倒なので、この命令を用意しました。
この命令は始めにPA0,1のビットをコールするアドレスに合わせて自動的に
セットして、その後call命令を生成します。これで、上位ビットを気にせず
サブルーチンコールできます。
この命令と併用してlset命令も必ず使用するはずです。そちらも参照してください。
|
lset addr11 |
この命令はPIC16C5X専用に用意されています。
アドレスaddr11で指定したビット(A9,10)の値に応じて、PA0,1の値を
セットします。A0〜8のビットは無視します。この命令で何をするのかというと
こういう理由からです。
lcallを使って他のバンクにコールする。
(PA0,1が(他のバンクの)サブルーチンのアドレスに設定されます)
↓
その(他のバンクの)サブルーチンからリターンする。
↓
call命令でPCと同じバンク内のサブルーチンにコールする。
(call命令はPA0,1を暗黙の内に参照する。しかし、最初のlcall命令でPA0,1は
他のバンクを指してしまっている。コールするとおかしなところに飛んでしまう。)
↓
暴走する。
この問題を回避するにはcall,jmp(goto)命令を使わず、lcall,ljmp命令のみ使用して、
コール・ジャンプすればいいのですが、同じバンク内のアドレスに何回もコールする場合
PA0,1のビットを設定する命令が多くなりプログラムの無駄が生じます。
lcall <他のバンクのアドレス> ;他のバンクにPA0,1を設定します。
lcall <PCと同じバンク内のアドレス>
lcall <PCと同じバンク内のアドレス>
lcall <PCと同じバンク内のアドレス>
lcall <PCと同じバンク内のアドレス>
lcall <PCと同じバンク内のアドレス>
そこで、lset命令を使い
lcall <他のバンクのアドレス> ;他のバンクにPA0,1を設定します。
lset $ ;この命令でPA0,1をPCと同じに設定し直す。
;(PCをPA0,1との同調をとる)
call <PCと同じバンク内のアドレス>
call <PCと同じバンク内のアドレス>
call <PCと同じバンク内のアドレス>
call <PCと同じバンク内のアドレス>
call <PCと同じバンク内のアドレス>
このようにすることで、8ワード分命令数が少なくてすみます。
|
mov fr,#lite |
|
mov fr1,fr2 |
|
mov fr,W |
|
mov option,#lite (move option register) |
|
mov option,fr |
|
mov option,W |
|
mov !port_fr,#lite |
PICの入出力レジスタの設定を行います。
port_frにポート位置(RA,RB,RC等)を設定します。頭の!マークを忘れないでください。
定数liteのビットが0の時出力ポート、1の時入力ポートとなります。
通常リセット直後は全ビット1(全て入力ポート)に設定されています。
だいたいのプログラムはリセットの後にこの命令を書いてI/Oピンの設定
を行う場合が多いようです。
この命令はtris命令に展開されるので、メモリページの切り替えはしません。
|
mov !port_fr,fr |
|
mov !port_fr,W |
|
mov W,#lite |
|
mov W,fr |
|
mov W,/fr |
|
mov W,fr-W |
|
mov W,++fr |
|
mov W,--fr |
|
mov W,< |
|
mov W,>>fr |
|
mov W,<>fr |
|
movb bit1,bit2 (MOVe Bit field) |
ビット単位の移動を行います。bit1,bit2で指定された以外のビットは影響を受けません。
bit2に入力ポートのビットを指定した場合は注意が必要です。
|
movb bit1,/bit2 |
|
movsz W,++fr |
|
movsz W,--fr |
|
neg fr |
ファイルレジスタfrの2の補数をとります。
|
not fr |
全ビットを反転します。それだけです。Zフラグが変化します。
パソコン等のCPUではこのニーモニックの方が一般的なような気がします>マイクロチップさん
|
not W |
全ビットを反転します。それだけです。Zフラグが変化します。
PICのインストラクションではWレジスタとのnot(に相当する)命令がない
為、FFhとXORを取ります。
|
or fr,#lite |
|
or fr1,fr2 |
|
or fr,W |
|
or W,#lite |
|
or W,fr |
|
ret (RETurn from subroutine) |
サブルーチンからリターンする命令です。return命令と基本的に同じですが、
この命令はretlw 0の命令に展開されるため、Wレジスタに0になりますので注意してください。
|
retw lite1[,lite2,lite3...] |
マイクロチップのインストラクションretlwと基本的に同じです。
違うのはオペランドを2個以上置くことが可能です。(retlw はオペランドを1つしか置けない)
|
rl fr |
|
rr fr |
|
sb bit |
|
sc |
|
setb bit (SET bit field) |
bitで指定されたビット位置を1にセットします。
この命令はマイクロチップのbsfインストラクションとまったく同じ動作です。
実行クロックは1サイクルです。
|
skip |
|
snb bit |
|
snc |
|
snz |
|
stc (SeT Carry flag) |
Cフラグを1にセットします。実行クロックは1サイクルです。
|
stz (SeT Zero flag) |
Zフラグを1にセットします。実行クロックは1サイクルです。
|
sub fr,#lite |
|
sub fr1,fr2 |
|
sub fr,W |
|
subb fr,bit |
|
swap fr |
|
sz |
|
test fr |
ファイルレジスタfrの値をテスト(0かそれ以外かチェック)します
frが0のときZフラグが1にセット、frが0以外の時Zフラグが0にクリアされます。
この命令はファイルレジスタがクリアされているかチェックする命令です。
|
test W |
Wレジスタが0かどうかテストします。結果はZフラグに反映します。
|
xor fr,#lite |
|
xor fr1,fr2 |
|
xor fr,W |
|
xor W,#lite |
|
xor W,fr |
|