| 落合正弘さん作のPICマイコン用アセンブラ「PA (Ver3.05)」 でマクロを使うときの注意 ・・・PAの落とし穴 |
2005-03-11
![]()
マクロ使用時の注意
| PICマイコンを使った私の製作物、すべて落合正弘さん作のアセンブラ「PA」を使用しています。 PICを使いはじめてだいぶ経つのですが、いまだにマイクロチップのニーモニックは馴染めません。 PAには独自の拡張ニーモニックがあらかじめ用意されているので、さほどの違和感無く便利に使わせてもらっています。 なにより「MS-DOS」で動くのがありがたいのです。 PICマイコンごときのプログラム開発にWindowsは要りません。(と、強がりを書いておきます) PAはマクロも備えているので、独自の処理を記述するときなど、便利に使えます。 さて、愛用していますPA、ちょっとした落とし穴に出会いましたので注意点を報告しておきます。 |
PAのマクロでビット指定したデータを使うときは、先に確定したアドレスに対してビット位置の指定をしなければなりません。 アドレスがまだ確定していないデータに対してビット位置を指定してしまうと、マクロ内でそのビットデータに対する実行コードが展開されないという異状が生じます。 この異状、残念ながらエラーメッセージとしての警告が出ないので、気がつくのにたいへん苦労します。 Pass1とPass2でラベルの位置にズレが生じるので、Phaseエラーとして警告が出てもよさそうなのですが、現PAでは警告が出ませんのでやっかいなのです。 異状の発生するプログラムを紹介しておきます。 (プログラムリストは等倍フォントでご覧ください) |
| ;***** 落合正弘さん作のPICアセンブラ PA ***** ; におけるマクロ使用の注意 ;* チップ名指定 .16f84 ;仮に指定 ;* configuration bit (必須) _fuse@ equ 2007h ;とりあえずincファイルは使わない _data@ equ 2100h ;***** マ ク ロ ***** ;* return bit on retb macro b btfsc b ;bit off ならスキップ return ;指定したビットがオンでリタ-ンするマクロ endm ;* フラグ ビット指定(データ出現の前に指定) f_ng equ f_00.0 ;NG flag この出現位置に注目 ;***** RAMデータエリア ***** org 20h f_00: ds 1 ;flag 0 data ビット指定するデータ ;* フラグ ビット指定(データ出現の後に指定) f_ok equ f_00.1 ;OK flag ←《1》データが出現した後に指定 ;***** プログラムエリア ***** org 0 ;ここからROM内 goto a1 ;ジャンプアドレスに注目 goto a2 goto a3 ;★ このジャンプ先を注目 nop a1: ;0004 retb f_ok ; これはok a2: ;0006 retb f_ng ;★ これがうまくアセンブルされないのだろう a3: ;0008 nop goto a1 goto a2 goto a3 ; 上を参照するこれはok ;--------------------------- ; 以降の後方参照でアドレスが狂ってしまう goto b1 ;★ アドレスが狂う nop b1: ;000E nop goto b1 ; 上を参照するこれはok ; 《1》の「f_ok」のようにデータが出現してからビット位置を ; 指定するようにしなければならない。 ; f_ngのようにデータ位置が確定していないままビット位置を指定した ; 場合それを使った外部マクロがアセンブルされコードが生成されない ; のではないだろうか。 ; 本来なら「phaseエラー」(pass1とpass2で生成したアドレスが異なる) ; あたりが出てくれてよさそうなのだが。 |
以下はそのアセンブルリストです。 行番号と不要行、コメントの一部を削っています。 「goto a3」と「goto b1」と書いている所に注目してください。 「a3」「b1」のアドレスと異なる場所に飛んでいくコードが生成されています。 ビット指定を使って指定したフラグ「f_ng」に対する実行コードが、パス1で生成されな いために、パス1とパス2で異なったラベルのアドレス値が発生しているのです。 このせいで、作ったプログラムが暴走します。 |
| ;* フラグ ビット指定(データ出現の前に指定) =0020.0 f_ng equ f_00.0 ;NG flag ;***** RAMデータエリア ***** 0020 org 20h 0020 f_00: ds 1 ;flag 0 data ;* フラグ ビット指定(データ出現の後に指定) =0020.1 f_ok equ f_00.1 ;OK flag 《1》 ;***** プログラムエリア ***** 0000 org 0 0000 2804 goto a1 0001 2806 goto a2 0002 2806 goto a3 ;★ これはおかしい 0003 0000 nop 0004 a1: ;0004 0004 18A0 0008 retb f_ok ; これはok 0006 a2: ;0006 0006 1820 0008 retb f_ng ;★ これがNG 0008 a3: ;0008 0008 0000 nop 0009 2804 goto a1 000A 2806 goto a2 000B 2808 goto a3 ; これはok ;--------------------------- ; 以降の後方参照でアドレスが狂ってしまう 000C 280C goto b1 ;★ アドレスが狂う 000D 0000 nop 000E b1: ;000E 000E 0000 nop 000F 280E goto b1 ; 上を参照するこれはok -- Symbol List -- _fuse@ : 2007 _data@ : 2100 f_00 : 0020 f_ok : 0020.1 a1 : 0004 a2 : 0006 a3 : 0008 b1 : 000E f_ng : 0020.0 |
| パス2ではちゃんとコードが生成されるのでアドレスに狂いは生じません。 ところがパス1では、まだ生成すべきデータが確定していないということなのでしょう、実行コードが作られないようなのです。 このためプログラムの下のほうにあるラベルにジャンプするアドレスに狂いが生じ、プログラムが思い通りに動かなくなってしまいます。 マクロを使ったときだけの異状のようですし、《1》のように記述すれば解決できますので、致命的ではありません。 ただ、こんなことがあるということを知っておかないと、原因追求と解決に往生します。 |
|
|
![]()