このドキュメントは http://edu.net.c.dendai.ac.jp/ 上で公開されています。
機械語とはコンピュータ(CPU)を動作させるための数値列の事です。 PIC 16F628A では 14bit で 1 つの命令を表します。 一方アセンブリ言語とはこれらの数値をその機能などが直観でわ かるように英単語や記号等を当てはめた物です。 アセンブリ言語で記述されたプログラムを機械語に直す事をアセンブル と言います。また、アセンブルを行うコンピュータプログラムを アセンブラと言います。 但し、アセンブリ言語をアセンブラと呼ぶ事もあります。
機械語やアセンブラでは頻繁に十六進数を使います。 PIC のデータシートの表記では、次のように複数の表記法があります。
また、二進数についても次の表記があります。
十進数については、通常の単なる数値による表記の他、次の表記もあります。
またメモリ中の特定のビットに注目する時に次の表記を使います。
アセンブリ言語は一つの機械語を機能と引数に分けて表現します。
機能の部分をmnemonic(ニモニック)と呼び、引数をオペラン
ドと言います。
例えば、00 0000 1000 0000
は W レジスタの内容を 0 番地の
メモリにコピーする機械語です。
また、00 0000 1000 0001
は W レジスタの内容を 1 番地のメ
モリにコピーする機械語です。
総称すると、00 0000 1fff ffff
は W レジスタの内容を fff
ffff 番地のメモリにコピーする機械語となります。
したがって、これらに対して機能を表すニモニックを movwf とし、fff ffff
部分をオペランドとします。
つまり、W レジスタの内容を 0 番地のメモリにコピーすることを、アセンブリ
言語で表現すると movwf 0
となります。
オペランドとして、メモリの番地の他、ビット位置や、定数(リテラル)、演算
結果の収納先などを指定します。
PIC をプログラミングする観点で見た時の、 PIC の特徴的なアーキテクチャ についてお話します。
我々が普段使っている Windows を使うパソコンでは、メモリは単一のもので、 プログラムとデータが共存しています。これを(フォン)ノイマン型コンピュー タと呼んでいます。 一方、PIC では、データシートの p.10 Figure 3-1 にあるように、 メモリにプロ グラム領域とデータ領域に明確な区分があり、共存していません。これを ハーバードアーキテクチャと言います (由来のハーバードマークI は世界初の汎用(リレー式)計算機(1944))。 プログラムをデータとして扱えないため、プログラムをメモリ上で扱う OS や コンパイラなどの実装は難しいという欠点はあります。 しかし PICの用途から考えると OS やコンパイラを使うことは無さそうなの で、問題無さそうです。 さらにこのようなアーキテクチャでは、CPU がプログラムを読み込む仕組みを 単純化できるなど長所もあります。 また PIC のようにプログラムの語長とデータの語長がそれぞれ 14bit と 8bit と異なるデザインも可能です。
PIC のプログラム領域は データシートの Figure 4-1(p.15) にあるよ うに、0h から 07ffh まであります。 電源を入れた時やリセットした時は 0 番地から実行されます。割り込みが発 生した時は 4 番地から実行されます。 プログラムカウンタは 13bit (0h〜1fffh)あります。領域を越えてアクセスし た場合、下位 11bit が有効になります。
goto 命令(p.121)、 call 命令(p.119) ではオペランドに 11 bit のみ指定し ます。 PIC 16F628A ではこれで十分です。 但し、仕様によると、 PCLATH の 3,4 bit がプログラムカウンタの上位 2 bit に入れられることになっています。
call 命令では、call 命令のある番地に 1 を加えた値がスタックに積まれま す。スタックは全部で 8 段しかありません。 return 命令(p. 125)でスタックに入っている番地がプログラムカウンタに入 れられます。
プログラムカウンタの下位 8bit は 2 番地のファイルレジスタになっていま す。 また上位 5bit は ah番地のファイルレジスタ PCLATH に対応しています。 したがって、下位 8bit に関しては通常のファイルレジスタ同様に演算が可能 です。これによりレジスタの値による相対ジャンプなどが実現できます。 (データシート p.28 4.3 節)
データシートの p.16 Figure 4-2にメモリの構造が載っています。 PIC の機械語では RAM 領域であるファイルレジスタを指定する領域は 7bit( 0h 〜 7fh ) しかありません。 したがって、27=128 個の領域しか指定できません。 そのため、多くのファイルレジスタが内蔵されている PIC ではファイルレジ スタ領域が 128Byte 毎に区切られています。 区切られた領域をそれぞれ BANK と言います。 但し、BANK 内のメモリには Special Function Register(SFR)や 共通領域と いった異なる機能をもった部分に区切られて います。 ユーザが自由に使える領域は BANK 0 の 20h から 7fh とBANK1 の a0h から efh と BANK2 の 120h から 14fh です。 これらは STATUS レジスタにある RP0, RP1 の値を変えながらアクセスします。 但し、 70h から 7fh はバンク切替えに関わらず常に同じオペランドでアクセ スできます。
Special Function Register は データシート pp.18-21 の Table 4-3 から 4-6 に構造が載っています。 この Special Function Register とはメモリバンクの先頭部分(0h から 1fh, 80h から 9fh など)にある、特殊な働きをするファイルレジスタです。
従来の CPU は数個から数十個のレジスタと呼ばれる CPU の内部メモリを持ち、 様々な機能を割り当ててました。これは通常のメモリ上のデータ領域とは働き が異なってました。 一方、PIC の Special Function Register はデータメモリ上にあります。 PIC でメモリ上にないのは W レジスタのみです。 PIC ではプログラムカウンタや演算結果のパターンを記憶するフラグレジスタ までメモリ上にあります。 これら W レジスタ以外の様々な特殊な働きをするレジスタにはそれぞれアド レスが割り当てられています。
PIC のファイルレジスタ領域は電源を切ると通常のメモリの内容は消えてしま います。 しかし、 EEPROM 領域と言う電源を切っても内容の消えないメモリも持ってい ます。但し、書き込み回数は 100 万回程度と寿命があるため、頻繁に値を変更 するような計算などには使用しない方が良いです。
電源を入れた時やリセットした時は 0 番地から実行が始まります。 一方割り込みが発生した時は 4 番地から実行が始まります (データシート p.15 Figure 4-1 )。 割り込みとは次の条件が発生した時のことを言います。 データシート p.107 14.5 節 を御覧下さい。
これらの条件に PIC が反応すると割り込みベクタと呼ばれる 4 番地からプログラムを実行します。 但し、これらに反応するかどうはレジスタの値で決まります。 割り込みを許可/不許可するための値やレジスタのことを割り込みマス クと言います。 これらの概要は データシートの pp.23-26 にある、option、intcon、pie1、 pir1 レジスタにあります。
PIC では割り込みベクタは一つしかありません。 つまり、全ての割り込みに対して 4 番地に制御が移ります。 したがって、複数の割り込みを取り扱う場合、どの割り込みが生じたかを調べ る必要があります。 これはファイルレジスタ intcon,pir1 の各ビットを調べます。
mov ax,bx ; ax レジスタの値を bx レジスタへ入れる
mov 2,ax ; 2 を ax レジスタに入れる
mov [2],ax ; メモリの 2 番地の内容を ax レジスタに入れる
Pentium のアセンブリ言語(アドレッシングモードあり)
Intel 社の Pentium などは RISC ではありません。
対義語として CISC(Complex
Instruction Set Computer 複合命令セットコンピュータ) と呼ばれています。
Pentium のアセンブラではオペランドが様々に変化します。
これをアドレッシングモードと呼びます。
レジスタからレジスタに値を移す命令も、リテラルからレジスタに値を移す命
令も、メモリの特定番地からレジスタに値を移す命令も同じ
movf 2,0 ; 2 番地のファイルレジスタの値を W レジスタに入れる
movlw 2 ; 2 を W レジスタに入れる
movwf 2 ; W レジスタの値を 2 番地のファイルレジスタに入れる
PIC のアセンブリ言語(アドレッシングモードなし)
一方 PIC ではオペランドの型毎に命令が異なります。例えば上記と似たよう な処理として、ファイルレジスタからワークレジスタに値を移す命令、リテラ ルからワークレジスタに値を移す命令は異なります。 また、PIC ではファイルレジスタとメモリは同一視出来ますので、特定番地か らワークレジスタに値を移す命令はファイルレジスタからワークレジスタに値 を移す命令と同じです。命令を記述すると次のようになります。
なお、これはアセンブリ言語の設計の話であって、CPU の性質ではありません。 ただ、CISC と違って RISC はアドレッシングモードの種類が少ないため、ア ドレッシングモードを加味したアセンブリ言語を作ってもそれほどメリットが ありません。 これがアドレッシングモードのないアセンブラを作った一因だと思われます。
データシートの TABLE 15-2 に全命令の表があります。 この表では「バイト指向ファイルレジスタ操作」「ビット指向ファイルレジス タ操作」「リテラル操作および制御操作」の三つに分類されています。 これはオペランド(引数)により区分しています。
結論としては、 TABLE 15-2 の分類は PIC 特有と言えますが、 RISC の特徴 を表しています。 PIC のアセンブリ言語はアドレッシングモードを考慮しません。 オペランドの型により分類されています。
演算結果が 0 かどうか、又は桁あふれ(オーバーフロー)を調べることができます。 これは STATUS という特別なレジスタが用意され、演算を監視しています。 演算で変化するフラグはデータシートの p.22 REGISTER 4-1 に書かれてます。 ここでフラグとはなんらかの状態を 0 か 1 で表すもののことを 言います。 例えば、演算結果 が 0 になると STATUS 中の Z フラグが 1 になります。 このフラグの中でm主に使うのは演算結果が 0 の時の Z フラグと、足し算の けた溢れと、引き算の借りが出なかった時に 1 になる C フラグです。
なお、ファイルレジスタの値が 0 かどうか判定するという特殊な命令
MOVF
があります。
これは移動命令ですが、移動先にファイルレジスタを指定すると、どこにも移
動しないという奇妙な命令です。
但し、その際、指定したファイルレジスタが 0 だと Z フラグが反応します。
STATUS の値に応じて次の命令を飛ばすスキップ命令があります。
これにより、演算結果の値に応じて処理を変えることができます。
スキップ命令は 4 種類あります。
他の CPU ではフラグレジスタに特化した命令がありますが、 PIC はフラグを特別
視した命令はありません。
しかし、その一方、任意のファイルレジスタのビットを調べられます。
指定したファイルレジスタのビットが 0 の時スキップする
btfsc
、 1 の時スキップする btfss
の他に、特
殊な命令としてファイルレジスタを 1 増減させて 0 の時にスキップする
incfsz
、decfsz
があります。
なお、メモリの BANK 構成(データシート p.16 Figure 4-2 など)を見れば分かりますが、どの BANK に設定しても、 STATUS レジスタは常に参照出来ます。
15-2 節には全ての命令の詳細が載っています。 ここでは一番先頭にある命令 ADDLW を例にデータシートの読み方を説明しま す。
11 | 111x | kkkk | kkkk |
ADDLW 0x15
00 | 0111 | dfff | ffff |
ADDWF REG1,0
ファイルレジスタをオペランドで指定する命令では、ファイルレジスタのアド レスは 7bit で、8bit 目となる二つ目のオペランドに destination(送り先) を指定します。 これは演算結果が 0 なら W レジスタに入れられ、 1 なら元のファイルレジ スタに戻されます。 ファイルレジスタに直接加算できるので、例えばプログラムカウンタに加算すること で W レジスタの値を加えた番地へジャンプすることなどもできます。これを 算術ジャンプと呼ぶことがあります。詳しくは RETLW 命令を参照 下さい。
00 | 1000 | dfff | ffff |
MOVF REG1,0
ADDWF は足し算をしましたが、 MOVF はデータの移動だけです。 しかも d=0 の時はファイルレジスタを W レジスタに入れることになりますが、 d=1 の時はファイルレジスタの値がそのままもどされます。 この場合、一見何もしない命令に見えますが、計算結果に応じてフラグレジス タの値が変化します。 もしファイルレジスタの値がもともと 0 の場合、 Z フラグが 1 にセットさ れます。 つまり、 MOVF で d=1 の場合、ファイルレジスタが 0 かどうかを調べるため の命令になります。
10 | 1kkk | kkkk | kkkk |
GOTO
is an uncoditional branch.
The eleven-bit immediate value is loaded into PC bits<10:0>.
The upper bits of PC are loaded from PCLATH<4:3>.
GOTO is a two-cycle instruction.
GOTO THERE
GOTO は PC(プログラムカウンタ) の値を変える命令です。 PC 自体は 13 bit ありますが、オペランドは 11bit 分のみです。 しかし、PIC 16F628A のアドレス空間はちょうど 11bit なので、 上位二桁を変える必要はありません。 したがって、 PCLATH<4:3> は常に 0 で良いことになります。
CALL は GOTO とほぼ同じですが、 CALL 命令のある番地の次の番地をスタック に積みます。このスタックに積まれた番地は RETURN 命令で使います。
10 | 0kkk | kkkk | kkkk |
HERE CALL THERE
00 | 0000 | 0000 | 1000 |
RETURN
RETURN はスタックに積まれた番地を PC に入れることにより、 CALL 命令の あった次の命令の場所に戻ります。
また、 PIC には RETLW という特別な命令があります。これは RETURN と同様 にスタックに積まれた番地を PC に入れる命令ですが、さらに指定したリテラ ルを W レジスタに入れます。 これによりサブルーチンから値を返すことが一命令でできます。 この命令を列挙し、 ADDWF による算術ジャンプと組み合わせると、複数のデー タをランダムアクセスしてW レジスタに入れることができます。 PIC は RAM 領域が少ないですが、この手法を用いることによりランダムアク セスできるデータをプログラム領域に置くことができます。
11 | 01xx | kkkk | kkkk |
CALL TABLE ; W contains table offset value
; W now has table values
...
TABLE ADDWF PC ; W = offset
RETLW k1 ; Begin table
RETLW k2
...
RETLW kn ; End of table
01 | 10bb | bfff | ffff |
HERE BTFSC REG,1
FALSE GOTO PROCESS_CODE
TRUE
...
BTFSC はファイルレジスタの特定のビットを検査する命令です。 W レジスタに対する命令がないことに注意します。 なお、b は固定位置しか指定できません。 W レジスタの検査や、パラメータを与えてビットを検査するには他の CPU と 同様に AND, OR 命令などを使います。
また、BTFSS はビットが 0 と 1 の動きが逆なだけで、同様の命令です。
00 | 1011 | dfff | ffff |
HERE DECFSZ REG1,1
GOTO LOOP
CONTINUE ...
DECFSZ はファイルレジスタを 1 減算し、 0 になったかどうかチェックしま す。 0 になったらスキップしますので、 DECFSZ の次に前方へ飛ぶ GOTO 命令を書 いておくと、指定したファイルレジスタの値に応じた繰り返し計算をすること になります。 なお、INCFSZ はファイルレジスタに 1 を加算する以外は同様の命令です。
アセンブリ言語はテキストファイルに記述します。 アセンブラのユーザーズマニュアル p.25 の Example 1-1 に示されているよ うに記述します。 ラベル、ニモニック、オペランドを空白で区切って記述します。 ラベルの前に空白があってはいけません。 また、セミコロン(;)の後ろはコメントとしてアセンブル時に無視されます。 ニモニックの位置には他にディレクティヴ、マクロなどを置くことができます。
ラベル ニモニック オペランド コメント
TRISA equ h'0085'
org 0x0008
start
banksel TRISA ; バンク切替え
clrf TRISA ; TRISA を 0 に
アセンブリ言語の定数はいろいろな表記方法があります。 アセンブラのユーザーズガイドの Table 3-3 に定数の表記法があります。
アセンブリ言語中で定数の演算式を書くことが出来ます。 アセンブラのユーザーズガイドの Table 3-4 にあるように C 言語で許されて いるような演算子がそのまま使えます。 但し、レジスタの内容は演算の対象ではありません。
アセンブラとはニモニックとオペランドから機械語を生成するものですが、 利便性を向上するためのアセンブラの機能があります。 ディレクティヴとはアセンブラに対する指示をする命令です。
良く使うディレクティヴを紹介します。
list p=16f628a
とすると使用プロセッサを 16F628A にするこ
とができます。
#include p16f628a.inc
として定義ファイルを読み込むと、各 Special Function Register の名前な
どが利用できるようになります。
なお、 p16f628a.inc は
c:\Program File\Microchip\MPASM Suite にあります。
p16f628a.inc の内容はプログラムを組む時重要になりますので、印刷してお
いて下さい。
PIC の動作モードを指定します。 動作モードの一覧はデータシート p.96 Register 14-1 にあります。 ここに示されている Configuration Word Register の値により PIC の動作が 決まります。 但し、このレジスタはプログラム領域の 2007h にあるため、PIC のプログラ ムからは変更できません。 __config で指定してプログラムを転送する時に一緒にこの Configuration Word Register も転送します。
設定できる項目は次の通りです。
本講義で関係ありそうなのは MCLRE とオシレータ切替えです。 これらの設定方法は、 p16f628a.inc ファイルの最後に列挙されている各設定 項目を全て and 演算(&)で結び、 __config に与えます。 以下に例を示します。但し設定項目が多く、一つの式にすると一覧性が悪くな るので、変数を使い、代入演算子(&=)を用いて計算しています。
variable env
env = _BOREN_OFF
env &= _CP_OFF
env &= DATA_CP_OFF
env &= _PWRTE_OFF
env &= _WDT_OFF
env &= _LVP_OFF
env &= _MCLRE_OFF
env &= _INTOSC_OSC_NOCLKOUT
__config env
連続したファイルレジスタ領域にラベルを付けます。 以下のようにすると wa0 が 0x20 に、 wa1 が 0x21 に、 wa2 が 0x22 に割 り当てられます。
cblock 0x20
wa0,wa1 ; wa0 and wa1 are counters.
wa2 ; Also wa2 is a counter.
endc
マクロを定義します。
さて、この節では実際にプログラムを作成する手順を説明します。
アセンブルしたプログラムはシミュレータで動作を観察できます。 (MPLAB IDE User's Guide: Part 4 MPLAB SIM) Debugger → Select Tool → MPLAB SIM を選ぶとソフトウェアシミュレータ を使えるようになります。 シミュレータはプログラムを一命令ずつ動かしたり、指定した所まで動かして 止めたり出来ます。
シミュレータを起動すると右上にテープレコーダのボタンのようなコントロー ルパネルが開きます。 矢印が二個あるのが animate と言い、視覚的に順々に命令を実行します。 なお、 View メニュー中に様々な PIC の状態を表示できる機能があります。 ファイルレジスタの一覧や、 Special Function Register をまとめて表示し たりできます。
プログラムリストの行をダブルクリックすると左側に赤い丸が付きます。 これを ブレークポイントと言います。 矢印一つの Run を実行すると、ブレークポイントで終了します。 これにより、プログラムの途中のレジスタの値などをチェックできます。
その他、一命令だけ実行する Step Into, Call 命令に関しては戻って来るま で一括で実行する Step over, サブルーチン中から抜け出すまで実行する Step out があります。
MPSIM でシミュレーションしている時に、 I/O PIN などに加える信号を変化 させるには、 Stimulus を使います (MPLAB IDE User's Guide: Part 4 MPLAB SIM: Chapter 14 Using Stimulus) 。
アセンブルして作られた HEX ファイルは次のようにして PIC に書き込みます。
前回のサンプルプログラム sw.asm の各行がどのような意味か、全て調べなさい。
前回のサンプルプログラム sw.asm を機能毎に区分し、各機能を説明しなさい。
前回のサンプルプログラム flash.asm の各行がどのような意味か、全て調べなさい。
前回のサンプルプログラム flash.asm を機能毎に区分し、各機能を説明しなさい。