第 3 回 アセンブリ言語のプログラミング

本日の内容


このドキュメントは http://edu.net.c.dendai.ac.jp/ 上で公開されています。

3-1. 準備

機械語とはコンピュータ(CPU)を動作させるための数値列の事です。 PIC 16F628A では 14bit で 1 つの命令を表します。 一方アセンブリ言語とはこれらの数値をその機能などが直観でわ かるように英単語や記号等を当てはめた物です。 アセンブリ言語で記述されたプログラムを機械語に直す事をアセンブル と言います。また、アセンブルを行うコンピュータプログラムを アセンブラと言います。 但し、アセンブリ言語をアセンブラと呼ぶ事もあります。

機械語やアセンブラでは頻繁に十六進数を使います。 PIC のデータシートの表記では、次のように複数の表記法があります。

  1. 数値の後に h を付加: Example 3-1 の MOVLW 55h など
  2. 数値の前に 0x を付加: Example 4-1 の MOVLW 0x20 など

また、二進数についても次の表記があります。

  1. シングルクォーテーションマークで括って後ろに b を付加: Example 6-1 中の MOVLW '00101111'b(ミス?)
  2. b の後にシングルクォーテーションマークで括る: Example 6-2 中の MOVLW b'xxxx0xxx'

十進数については、通常の単なる数値による表記の他、次の表記もあります。

  1. d の後にシングルクォーテーションマークで括る: d'123' など (MPASM Asembler User's Guide: Table 3-3)
  2. ピリオドの後に数値を書く: .123 など (MPASM Asembler User's Guide: Table 3-3)

またメモリ中の特定のビットに注目する時に次の表記を使います。

  1. レジスタ名<n> レジスタの中の n bit 目(0≤n≤7): 4.2.2.5 節の note 中の INTCON<7> など
  2. レジスタ名<m:n> レジスタの中の m bit から n bit まで(0≤m<n≤7): Registere 4-2 中の PS<2:0>など

アセンブリ言語は一つの機械語を機能と引数に分けて表現します。 機能の部分を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 となります。 オペランドとして、メモリの番地の他、ビット位置や、定数(リテラル)、演算 結果の収納先などを指定します。

3-2. PIC マイコンのアーキテクチャ

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

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 レジスタ以外の様々な特殊な働きをするレジスタにはそれぞれアド レスが割り当てられています。

EEPROM

PIC のファイルレジスタ領域は電源を切ると通常のメモリの内容は消えてしま います。 しかし、 EEPROM 領域と言う電源を切っても内容の消えないメモリも持ってい ます。但し、書き込み回数は 100 万回程度と寿命があるため、頻繁に値を変更 するような計算などには使用しない方が良いです。

割り込み

電源を入れた時やリセットした時は 0 番地から実行が始まります。 一方割り込みが発生した時は 4 番地から実行が始まります (データシート p.15 Figure 4-1 )。 割り込みとは次の条件が発生した時のことを言います。 データシート p.107 14.5 節 を御覧下さい。

  1. RB0/INT ポートへの信号
  2. タイマ TMR0 がオーバーフローした時
  3. RB4 から RB7 のどれかが変化した時
  4. コンパレータ(電圧比較器)の割り込み
  5. USART の TX(送信)割り込み
  6. USART の RX(受信)割り込み
  7. CCP 割り込み
  8. タイマ TMR1 がオーバフロー
  9. タイマ TMR2 がオーバフロー
  10. EEPROM割り込み

これらの条件に PIC が反応すると割り込みベクタと呼ばれる 4 番地からプログラムを実行します。 但し、これらに反応するかどうはレジスタの値で決まります。 割り込みを許可/不許可するための値やレジスタのことを割り込みマス クと言います。 これらの概要は データシートの pp.23-26 にある、option、intcon、pie1、 pir1 レジスタにあります。

PIC では割り込みベクタは一つしかありません。 つまり、全ての割り込みに対して 4 番地に制御が移ります。 したがって、複数の割り込みを取り扱う場合、どの割り込みが生じたかを調べ る必要があります。 これはファイルレジスタ intcon,pir1 の各ビットを調べます。

3-3. 命令セット

分類法


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 のアセンブラではオペランドが様々に変化します。 これをアドレッシングモードと呼びます。 レジスタからレジスタに値を移す命令も、リテラルからレジスタに値を移す命 令も、メモリの特定番地からレジスタに値を移す命令も同じ MOV 命令です。 しかし、レジスタ同士に対する機械語とメモリをアクセスする機械語は実際に はことなります。 これらはオペランドの記述方法により区別され、別々の機械語に翻訳されます。


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 の時にスキップする incfszdecfsz があります。

なお、メモリの BANK 構成(データシート p.16 Figure 4-2 など)を見れば分かりますが、どの BANK に設定しても、 STATUS レジスタは常に参照出来ます。

詳細の読み方

15-2 節には全ての命令の詳細が載っています。 ここでは一番先頭にある命令 ADDLW を例にデータシートの読み方を説明しま す。

ADDLW

  1. ADDLW Add Literal and W
  2. Syntax: [label] ADDLW k
  3. Operands: 0≤ k ≤ 255
  4. Operation: (W)+k→(W)
  5. Status Affected: C, DC, Z
  6. Encoding:
    11111xkkkkkkkk
  7. Description: The contents of the W register are added to the eight bit literal `k' and the result is placed in the W regster.
  8. Words: 1
  9. Cycles: 1
  10. Example: ADDLW 0x15
    Before Instruction
    W = 0x10
    After Instruction
    W = 0x25
  1. 最初の ADDLW はこの機械語に割り当てられた名前です。 これは ニーモニック(mnemonic)と呼ばれます。
  2. Syntax はアセンブリ言語の文法を表しています。角カッコ([]) 内は省略 可能です。 k はオペランドを示しています。
  3. Operands で、指定できるオペランド k の範囲が 0 から 255 までだと示 しています。
  4. Operation では実際の機械語の動作を示しています。 丸カッコで括られた W は W レジスタの値を意味します。したがって、 この機械語では W レジスタの内容と k の和を W レジスタに入れています。
  5. Status Affected とは、演算結果において変化する可能性のある Status レジスタのフラグを示しています。この場合、桁あふれの C, DC, ゼロを示す Z が変わる可能性があることを示しています。
  6. Encoding では実際の機械語がどうなるか示しています。 x は 0 か 1 かどちらでも良いことを示しています。 したがって、 111110kkkkkkkk か 111111kkkkkkkk のどちらでもこの ADDLW を示します。
  7. Description は文章による命令の説明です。 この命令の場合は「W レジスタの内容は 8 bit のリテラル『k』に加えられ、 結果は W レジスタに置かれる」いう意味です。
  8. Words は機械語の命令長で、 14bit が 1word になります。
  9. Cycles はこの機械語が実行される時間(マシンサイクル)を意味します。 データシートの p.13 Figure 3-2 にあるように、 CPU クロック 4 つ分で一 つの命令を実行します。 但し、これはパイプライン処理を行っています。 データシートの同じページの Example 3-1 にあるように、直前の機械語を処 理している間に、Fetch と呼ばれる命令の先読み機構が働きます。 そのため、一つの命令に対して読み込みと、処理の 2 つステップが必要にな りますが、これが順に平行して行われるため、実質の処理時間は 1 マシンサ イクル(4 クロック)で済みます。 但し、 goto や call やスキップ命令など、プログラムの実行する順序を変え る命令の場合、先読みした命令は無駄になるので、実行するのに 2 マシンサイ クルかかります。

ADDWF

  1. ADDWF Add W and f
  2. Syntax: [label] ADDWF f,d
  3. Operands: 0≤ f ≤ 127
    d ∈ [0,1]
  4. Operation: (W)+(f)→(dest)
  5. Status Affected: C, DC, Z
  6. Encoding:
    000111dfffffff
  7. Description: Add the contents of the W register with register `f'. If `d' is `0', the result is stored in the W register. If `d' is `1', the result is stored back in register `f'.
  8. Words: 1
  9. Cycles: 1
  10. Example: ADDWF REG1,0
    Before Instruction
    W = 0x17
    REG1 = 0xC2
    After Instruction
    W = 0xD9
    REG1 = 0xC2
    Z = 0
    DC = 0
    C = 0

ファイルレジスタをオペランドで指定する命令では、ファイルレジスタのアド レスは 7bit で、8bit 目となる二つ目のオペランドに destination(送り先) を指定します。 これは演算結果が 0 なら W レジスタに入れられ、 1 なら元のファイルレジ スタに戻されます。 ファイルレジスタに直接加算できるので、例えばプログラムカウンタに加算すること で W レジスタの値を加えた番地へジャンプすることなどもできます。これを 算術ジャンプと呼ぶことがあります。詳しくは RETLW 命令を参照 下さい。

MOVF

  1. MOVF Move f
  2. Syntax: [label] MOVF f,d
  3. Operands: 0≤ f ≤ 127
    d ∈ [0,1]
  4. Operation: (f)→(dest)
  5. Status Affected: Z
  6. Encoding:
    001000dfffffff
  7. The contents of register `f' is moved to a destination dependent upon the status of `d'. If d=0, destination is W register. If d=1, destination is file register `f' itself. d=1 is useful to test a file register since status flag `Z' is affected.
  8. Words: 1
  9. Cycles: 1
  10. Example: MOVF REG1,0
    After Instruction
    W = REG1
    If REG1=0, Z=1 else Z=0.

ADDWF は足し算をしましたが、 MOVF はデータの移動だけです。 しかも d=0 の時はファイルレジスタを W レジスタに入れることになりますが、 d=1 の時はファイルレジスタの値がそのままもどされます。 この場合、一見何もしない命令に見えますが、計算結果に応じてフラグレジス タの値が変化します。 もしファイルレジスタの値がもともと 0 の場合、 Z フラグが 1 にセットさ れます。 つまり、 MOVF で d=1 の場合、ファイルレジスタが 0 かどうかを調べるため の命令になります。

GOTO, CALL

  1. GOTO Unconditional Branch
  2. Syntax: [label] GOTO k
  3. Operands: 0≤ k ≤ 2047
  4. Operation: k→PC<10:0>
    PCLATH<4:3>→PC<12:11>
  5. Status Affected: None
  6. Encoding:
    101kkkkkkkkkkk
  7. 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.
  8. Words: 1
  9. Cycles: 2
  10. Example: GOTO THERE
    After Instruction
    PC = address THERE

GOTO は PC(プログラムカウンタ) の値を変える命令です。 PC 自体は 13 bit ありますが、オペランドは 11bit 分のみです。 しかし、PIC 16F628A のアドレス空間はちょうど 11bit なので、 上位二桁を変える必要はありません。 したがって、 PCLATH<4:3> は常に 0 で良いことになります。

CALL は GOTO とほぼ同じですが、 CALL 命令のある番地の次の番地をスタック に積みます。このスタックに積まれた番地は RETURN 命令で使います。

  1. CALL Call Subroutine
  2. Syntax: [label] CALL k
  3. Operands: 0≤ k ≤ 2047
  4. Operation: (PC)+1→TOS, k→PC<10:0>
    PCLATH<4:3>→PC<12:11>
  5. Status Affected: None
  6. Encoding:
    100kkkkkkkkkkk
  7. Call Subroutine. First, return address(PC+1) is pushed onto the stack. The eleven-bit immediate value is loaded into PC bits<10:0>. The upper bits of PC are loaded from PCLATH<4:3>. CALL is a two-cycle instruction.
  8. Words: 1
  9. Cycles: 2
  10. Example: HERE CALL THERE
    After Instruction
    TOS = Address HERE
    PC = Address THERE

RETURN, RETW

  1. RETURN Return from Subroutine
  2. Syntax: [label] RETURN
  3. Operands: None
  4. Operation: TOS→PC
  5. Status Affected: None
  6. Encoding:
    00000000001000
  7. Return from subroutine. The stack is POPed and the top of the stack(TOS) is loaded into the program counter. This is a two-cycle instruction.
  8. Words: 1
  9. Cycles: 2
  10. Example: RETURN
    After Instruction
    PC = TOS

RETURN はスタックに積まれた番地を PC に入れることにより、 CALL 命令の あった次の命令の場所に戻ります。

また、 PIC には RETLW という特別な命令があります。これは RETURN と同様 にスタックに積まれた番地を PC に入れる命令ですが、さらに指定したリテラ ルを W レジスタに入れます。 これによりサブルーチンから値を返すことが一命令でできます。 この命令を列挙し、 ADDWF による算術ジャンプと組み合わせると、複数のデー タをランダムアクセスしてW レジスタに入れることができます。 PIC は RAM 領域が少ないですが、この手法を用いることによりランダムアク セスできるデータをプログラム領域に置くことができます。

  1. RETLW Return with Literal in W
  2. Syntax: [label] RETLW k
  3. Operands: 0≤ k ≤ 255
  4. Operation: k→(W);
    TOS→PC
  5. Status Affected: None
  6. Encoding:
    1101xxkkkkkkkk
  7. The W register is loaded with the eight-bit literal `k'. The program counter is loaded form the top of the stack(the return address). This is a two-cycle instruction.
  8. Words: 1
  9. Cycles: 2
  10. Example:
    
          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
    
    Before Instruction
    W = 0x07
    After Instruction
    W = value of k8

BTFSC, BTFSS

  1. BTFSC Bit test f, Skip if Clear
  2. Syntax: [label] BTFSC f,b
  3. Operands: 0≤ f ≤ 127
    0≤ b ≤ 7
  4. Operation: skif if (f<b>)=0
  5. Status Affected: None
  6. Encoding:
    0110bbbfffffff
  7. if bit `b' in register `f' is `0', then the next instruction is skipped. if bit `b' is `0', then the next instruction fetched during the current instruction execution is discarded, and a NOP is executed instead, making this a two-cycle instruction.
  8. Words: 1
  9. Cycles: 1(2)
  10. Example:
    
    HERE  BTFSC  REG,1
    FALSE GOTO   PROCESS_CODE
    TRUE  
          ...
    
    Before Instruction
    PC = address HERE
    After Instruction
    if REG<1>=0,
    PC = address TRUE
    if REG<1>=1,
    PC = address FALSE

BTFSC はファイルレジスタの特定のビットを検査する命令です。 W レジスタに対する命令がないことに注意します。 なお、b は固定位置しか指定できません。 W レジスタの検査や、パラメータを与えてビットを検査するには他の CPU と 同様に AND, OR 命令などを使います。

また、BTFSS はビットが 0 と 1 の動きが逆なだけで、同様の命令です。

DECFSZ, INCFSZ

  1. DECFSZ Decriment f, Skip if 0
  2. Syntax: [label] DECFSZ f,d
  3. Operands: 0≤ f ≤ 127
    d ∈ [0,1]
  4. Operation: (f)-1→(dest); skip if result = 0
  5. Status Affected: None?
  6. Encoding:
    001011dfffffff
  7. The contents of register `f' are decrimented. If `d' is `0', the result is placed in the W register. If `d' is `1', the result is placed back in register `f'. If the result is `0', the next instruction, which is already fetched, is discarded. A NOP is executed instead making it a two-cycle instruction.
  8. Words: 1
  9. Cycles: 1(2)
  10. Example:
    
    HERE     DECFSZ  REG1,1
             GOTO    LOOP
    CONTINUE      ...
    
    Before Instruction
    PC = address HERE
    After Instruction
    REG1 = REG1 - 1
    if REG1 = 0,
    PC = address CONTINUE
    if REG1 ≠ 0,
    PC = address HERE + 1

DECFSZ はファイルレジスタを 1 減算し、 0 になったかどうかチェックしま す。 0 になったらスキップしますので、 DECFSZ の次に前方へ飛ぶ GOTO 命令を書 いておくと、指定したファイルレジスタの値に応じた繰り返し計算をすること になります。 なお、INCFSZ はファイルレジスタに 1 を加算する以外は同様の命令です。

3-4. アセンブリ言語

基本書式

アセンブリ言語はテキストファイルに記述します。 アセンブラのユーザーズマニュアル p.25 の Example 1-1 に示されているよ うに記述します。 ラベル、ニモニック、オペランドを空白で区切って記述します。 ラベルの前に空白があってはいけません。 また、セミコロン(;)の後ろはコメントとしてアセンブル時に無視されます。 ニモニックの位置には他にディレクティヴ、マクロなどを置くことができます。


ラベル  ニモニック オペランド コメント

TRISA   equ     h'0085'
	org	0x0008
start
        banksel TRISA    ; バンク切替え
	clrf	TRISA    ; TRISA を 0 に

リテラル

アセンブリ言語の定数はいろいろな表記方法があります。 アセンブラのユーザーズガイドの Table 3-3 に定数の表記法があります。

二進数
b'001010'
八進数
o'257'
十進数
d'901' または .901
十六進数
h'abcd' または 0xabcd
アスキーコード
a'text' または 'text'

演算

アセンブリ言語中で定数の演算式を書くことが出来ます。 アセンブラのユーザーズガイドの Table 3-4 にあるように C 言語で許されて いるような演算子がそのまま使えます。 但し、レジスタの内容は演算の対象ではありません。

ディレクティヴ

アセンブラとはニモニックとオペランドから機械語を生成するものですが、 利便性を向上するためのアセンブラの機能があります。 ディレクティヴとはアセンブラに対する指示をする命令です。

良く使うディレクティヴを紹介します。

list
アセンブラの動作を変化させるディレクティヴです。 list p=16f628a とすると使用プロセッサを 16F628A にするこ とができます。
#include
C 言語同様にファイルを読み込みます。MP IDE には各 PIC プロセッサご とに定義ファイルが用意されています。 #include p16f628a.inc として定義ファイルを読み込むと、各 Special Function Register の名前な どが利用できるようになります。 なお、 p16f628a.inc は c:\Program File\Microchip\MPASM Suite にあります。 p16f628a.inc の内容はプログラムを組む時重要になりますので、印刷してお いて下さい。
#define
定数を定義します。再定義できません。
equ
任意の値を持つラベルを定義します。再定義できません。
variable と =
変数を宣言し、値を代入します。 #define と違い何度でも代入できます。 この右辺には C 言語と同じように演算子を使った式を書く事が出来ます。 (アセンブラマニュアル p.43 Table 3-4)
__config

PIC の動作モードを指定します。 動作モードの一覧はデータシート p.96 Register 14-1 にあります。 ここに示されている Configuration Word Register の値により PIC の動作が 決まります。 但し、このレジスタはプログラム領域の 2007h にあるため、PIC のプログラ ムからは変更できません。 __config で指定してプログラムを転送する時に一緒にこの Configuration Word Register も転送します。

設定できる項目は次の通りです。

  1. CP プログラムメモリコード保護
  2. CPD データコード保護
  3. LVP 低電圧プログラミング
  4. BOREN
  5. MCLRE RA5/MCLRをリセット信号に使うか、 入力ピンに使うか
  6. PWRTE 電源投入タイマ
  7. オシレータ(クロック)の切替え: 内蔵(4MHz)にするか外部にするか

本講義で関係ありそうなのは 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
cblock, endc

連続したファイルレジスタ領域にラベルを付けます。 以下のようにすると wa0 が 0x20 に、 wa1 が 0x21 に、 wa2 が 0x22 に割 り当てられます。


	cblock 0x20
	wa0,wa1  ; wa0 and wa1 are counters.
	wa2      ; Also wa2 is a counter.
	endc
org
実際のプログラムを置く始点を指定します。
banksel
指定したファイルレジスタのあるバンクへ切替えます。
end
プログラムの最後を示します。これが無いとアセンブラはエラーを発生さ せます。
macro, endm

マクロを定義します。

3-5. アセンブル

さて、この節では実際にプログラムを作成する手順を説明します。

  1. MP IDE を起動します。
  2. 「File→New」で新たな編集画面を開きます。
  3. プログラムを入力します。
  4. 「File→Save as」でプログラムを保存します。
  5. 「Project→Quick Build xxx.asm」でアセンブルします。
  6. アセンブルエラーが出た場合、エラーをダブルクリックするとエラーの出 た行へカーソルが移動します。

3-6. シミュレータを使ったデバッグ

アセンブルしたプログラムはシミュレータで動作を観察できます。 (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) 。

3-7. 実行

アセンブルして作られた HEX ファイルは次のようにして PIC に書き込みます。

  1. USB シリアル変換器を介して、 PIC プログラマをパソコンに繋ぎ、電源 を入れます。
  2. マイコンピュータのプロパティからデバイスマネージャを起動します。
  3. ポートの表示から、接続しているUSB シリアル変換器の COM ポート番号 を調べます。
  4. PIC Writer 509 を起動します。
  5. オプションタブを選択し、使用している COM ポートを選択します。
  6. version ボタンを押して、 PIC プログラマのバージョンが正しく表示さ れることを確認します。
  7. DEVICE 欄で PIC 16F628A を選択します。
  8. LOAD ボタンを押してアセンブルして出来た HEX ファイルを選択し、読み 込みます。
  9. プログラマの切替えスイッチを操作し、 18pin モードにします。
  10. LED のガイドに合わせてPIC を差し込みます。
  11. PROGRAM ボタンを押して書き込みます。 書き込みがうまく行かない場合は一旦ERASE ボタンを押してから再度 PROGRAM ボタンを押します。
  12. PIC を取り外し、実行環境に取り付けて、電源を入れ動作させます。

3-8. 演習問題

演習3-1

前回のサンプルプログラム sw.asm の各行がどのような意味か、全て調べなさい。

演習3-2

前回のサンプルプログラム sw.asm を機能毎に区分し、各機能を説明しなさい。

演習3-3

前回のサンプルプログラム flash.asm の各行がどのような意味か、全て調べなさい。

演習3-4

前回のサンプルプログラム flash.asm を機能毎に区分し、各機能を説明しなさい。


坂本直志 <sakamoto@c.dendai.ac.jp>
東京電機大学工学部情報通信工学科