その退避先のアドレスをうまく決めておかないと、
マクロの中から別のマクロを呼び出したときに、
同じ場所に上書きしてしまうかもしれません。
こういう場合は、マクロ内でローカルなメモリ、
つまりローカル変数を使いたいところです。
結局マクロというのは呼ばれるたびに展開されるわけなので、
その都度メモリを適切に割り振ってやれば良いのですが、
これは、意外と単純な仕組みで実現できます。
; ローカル変数用に使う領域の定義
constant _VAR_first = 0x74
constant _VAR_last = 0x7b
variable _VAR_pointer = _VAR_first
variable vptr = 0
; N1バイトのメモリを確保する。
; vptrが、確保したメモリの先頭を指す。
valloc macro N1
vptr = _VAR_pointer
_VAR_pointer += N1
if _VAR_pointer > _VAR_last+1
error "valloc ran out of space"
endif
endm
; N1バイトのメモリを解放する。
; vallocと対で使う必要がある。
vfree macro N1
_VAR_pointer -= N1
vptr = 0
if _VAR_pointer < _VAR_first
error "vfree mismatch"
endif
endm
マクロの最初に valloc 、最後に vfree を記述して、
そのマクロの中で使うローカル変数の量を指定します。
valloc 直後に vptr の値をローカルなマクロ変数に入れたら、
あとはマクロの引数などと同じように使うことができます。
example macro
valloc 3 ; 3個のローカル変数を確保
local T1 = #v(vptr)
local T2 = #v(vptr+1)
local T3 = #v(vptr+2)
;
movwf T1 ; <-みたいにして使える
;
vfree 3 ; メモリ解放
endm
実行時に動的にメモリを確保しているわけじゃなくて、
あくまでもマクロ展開時に割り当てているので、
実行時の動作は普通にアドレスを直接記述したのと同じです。
ただローカル変数といってもマクロ内でローカルなだけなので、
サブルーチンや割り込みのことまで考えると、
・マクロの中からサブルーチンを呼び出さない
・割り込みの時はローカル変数領域全体を退避する
・あるいは割り込み処理ではローカル変数を使わない
とかの対策が必要になります。
0 件のコメント:
コメントを投稿