■ BASCOM-AVR (DEMO) の使用方法 ■

インライン・アセンブラの使用方法
 
BASCOM-AVRは、BASICプログラムの中に、アセンブラ命令を記述することができます。

● まえがき
 
 ・私のマイコンとの関わりは、インテル8080から始まり、数年前まで使い慣れた8085やZ-80を
  使い続けてきた、生きた化石のような存在でした。
 ・近年、雑誌やネットでは、PICマイコンなどの話題が大半を占め、価格も安いことから、ようやく
  乗り換える決心をしました。
 
 ・ところが、PICのアセンブラを見て意気消沈、これは全部おぼえ直しだ・・・。
演算はWレジスターのみ (MC6800を思い出した)
複雑なバンク切り替え
見慣れない命令セットと、逆になっている演算表記

 ・そんな時、AVRマイコンには、無料で試用できるBASICコンパイラがあることを知り、即座に
  AVR派に!
 ・BASCOM-AVRを使用しながら、インラインアセンブラを見てみると、見覚えのある命令がずらり。
32個もある豊富な演算レジスター (MC68000よりも多い)
16Bitの直線的なメモリーロケーション
8080やZ-80に似た命令語と演算表記 (LD,ST,ADD,INC,IN,OUT,PUSH,POPなど)
 
 ・30分ほど命令一覧表を見て、ほとんど理解できてしまいました。


● BASICとアセンブラの混在
 
 現在、私のAVRソフトウェア制作は、まずBASICで気楽に記述し、デバッグが完了した後に、
 処理速度やプログラム容量が問題になっている部分を、インラインアセンブラに書き換えると言う
 方法をとっています。
 
 ・ハードウェアを制御する内部レジスターへの書き込みは、必然的にマニュアル片手のめんどうな
  作業になりますが、BASICならば、レジスター名やビット名を気にすることなく制御できるので、
  ミスも減ります。
 
 ・色々な外部接続機器(表示器等)にも対応しているため、わざわざマニュアルとオシロスコープを
  見ながら、制御用のプログラムを組まずに済みます。
 
 ・BASCOM-AVRは、かなり簡潔なアセンブラを出力しますが、汎用性のため、無駄なレジスターの
  待避や、必要以上の処理ルーチンが組み込まれる事もあり、特に割り込み処理ではアセンブラ
  に書き換える必要性が出てきます。


● アセンブラの記述方法
 
 BASCOM-AVRでは、BASICとアセンブラの境を気にすることなく記述することができます。
 
     Dta = Dta * 100
     Dtb = 20
$asm
     LDS R16 , {Dta}
     LDS R17 , {Dtb}
     ADD R16 , R17
     STS {Dta} , R16
$end asm
     Print Dta
変数[Dta]を100倍する
変数[Dtb]に20を代入する
ここからアセンブラ命令であることを宣言
R16に変数[Dta]の内容を読み込む
R17に変数[Dtb]の内容を読み込む
R16とR17を加算し、R16に格納する
変数[Dta]にR16の内容を書き込む
ここでアセンブラ命令が終わりであることを宣言
変数[Dta]の内容をターミナルへ出力する
BASIC文法
BASIC文法

アセンブラ命令
アセンブラ命令
アセンブラ命令
アセンブラ命令

BASIC文法
 
 ・実際には、$asm、$end asm宣言が無くても、命令語によってアセンブラ命令であると認識され
  ますが、[SUB]、[SWAP]、[CALL]、[OUT] 命令は、BASIC文法と重なるため、[!CALL]の様に、
  (!)エクスクラメーション・マークを命令の前に付けて記述することも可能です。

 ・変数の内容をレジスターに読み込むには、上記の例のように、変数名をブラケット { } で囲みます。
 
 ・また、間接アドレッシングを可能にするため、アセンブラの支援命令として「LOADADR」命令が
  用意されています。
Loadadr Dta , X
ペアレジスタ [X] または [Z] に、変数が格納されているメモリーのアドレスを読み込みます
   注意. [Y] レジスターは、ソフトウェア・スタック・ポインタに使用されているため、使用できません。
 
 ・ラベル名のアドレスを読み込むには、次の命令を使用します。
LDI ZL , Low(Lab * 2)   Labはラベル名
LDI ZH , High(Lab * 2)

 ・下記のレジスターは、BASCOM-AVRが使用しているため、ユーザーが使用する場合には、
  PUSH,POP命令で退避が必要になります。
R4,R5
R6
R8,R9
R23
R0
スタック・フレームおよびtempデータの保管用
各種フラグを格納するビット変数
READ命令のポインター
[IN]、[OUT]、[SBI]、[CBI]命令変換用
[SBIC]、[SBIS]命令変換用

 ・新しいAVRで、拡張I/Oレジスタを搭載しているチップでは、[IN]、[OUT]、[SBI]、[CBI]、[SBIC]、
  [SBIS]命令が、拡張I/Oレジスタに対して、16Bitアドレッシングを使用しないとアクセスできない
  ため、コンパイラが自動的に、R23またはR0を使用する命令に変換します。
 ・マニュアルには、R23のみを使用すると言う表現ですが、[SBIC]、[SBIS]命令はR0を使用します。
 ・プログラムソース上では気がつかないので、注意が必要です。
 ・特に、割り込み処理内で上記の命令を使用する場合には、必ずR23またはR0をPUSH,POP命令で
  退避するか、この命令を使用しない記述に変更して下さい。
 ・$NOTRANSFORM On」命令を記述しておくと、自動変換が停止され、変換の必要がある
  命令行にエラーメッセージが表示されます。



● 割り込み処理でのアセンブラ
 
 BASICの「ON interrupt」命令で割り込み処理を記述した場合、割り込みルーチンの前後には、
 ほとんどのレジスターを待避するためのPUSH,POP命令が入ります。
 
 ・AVRは、レジスターが多いことで演算には良いのですが、割り込み処理では、逆に多くの
  レジスターを待避しなければならなくなります。
 ・特にコンパイラでは、どのレジスタが使われるのかまで判断していないため、下記の様に大量の
  PUSH,POP命令が入り、これだけでもかなりの処理時間を取られてしまいます。
 
割り込みルーチンの前 割り込みルーチンの後
PUSH R0
PUSH R1
PUSH R2
PUSH R3
PUSH R4
PUSH R5
PUSH R7
PUSH R10
PUSH R11
PUSH R16
PUSH R17
PUSH R18
PUSH R19
PUSH R20
PUSH R21
PUSH R22
PUSH R23
PUSH R24
PUSH R25
PUSH XL
PUSH XH
PUSH YL
PUSH YH
PUSH ZL
PUSH ZH
IN R24,SREG
PUSH R24

POP R24
OUT SREG,R24
POP ZH
POP ZL
POP YH
POP YL
POP XH
POP XL
POP R25
POP R24
POP R23
POP R22
POP R21
POP R20
POP R19
POP R18
POP R17
POP R16
POP R11
POP R10
POP R7
POP R5
POP R4
POP R3
POP R2
POP R1
POP R0
RETI
R6、R8、R9
R12、R13、R14、R15は
待避されません。


割り込みルーチン内で
Single型の浮動小数点
変数を使用する場合は、
ユーザーがR12〜R15を
待避しなければなりません。

 ・そこで、「ON interrupt」命令には、「NOSAVE」と言うオプションがあり、これを付けると上記の
  退避命令がすべて入らなくなるので、ユーザーがアセンブラルーチンで使用するレジスタのみを
  待避することができるようになります。
 
 ・「アセンブラの記述方法」の項でも記載しましたが、割り込みルーチン内で、拡張I/Oレジスタに
  対する、[IN]、[OUT]、[SBI]、[CBI]、[SBIC]、[SBIS]命令を使用した場合は、R23またはR0が
  自動的に使用されるため、必ずR23またはR0を待避するようにして下さい。




   電子工作の部屋 Top へ 前のページへ戻る