赤と緑のLED。
くっつけてエポキシでモールド。
見た目は悪いけど、これで2色LEDに...
なるわけないか!
表面を削ってみたらどうかな?
微妙。。
2008/06/02
PICの小技: ローカル変数
たとえばマクロ内の処理でWをいったん退避したい場合、
その退避先のアドレスをうまく決めておかないと、
マクロの中から別のマクロを呼び出したときに、
同じ場所に上書きしてしまうかもしれません。
こういう場合は、マクロ内でローカルなメモリ、
つまりローカル変数を使いたいところです。
結局マクロというのは呼ばれるたびに展開されるわけなので、
その都度メモリを適切に割り振ってやれば良いのですが、
これは、意外と単純な仕組みで実現できます。
マクロの最初に valloc 、最後に vfree を記述して、
そのマクロの中で使うローカル変数の量を指定します。
valloc 直後に vptr の値をローカルなマクロ変数に入れたら、
あとはマクロの引数などと同じように使うことができます。
実行時に動的にメモリを確保しているわけじゃなくて、
あくまでもマクロ展開時に割り当てているので、
実行時の動作は普通にアドレスを直接記述したのと同じです。
ただローカル変数といってもマクロ内でローカルなだけなので、
サブルーチンや割り込みのことまで考えると、
・マクロの中からサブルーチンを呼び出さない
・割り込みの時はローカル変数領域全体を退避する
・あるいは割り込み処理ではローカル変数を使わない
とかの対策が必要になります。
その退避先のアドレスをうまく決めておかないと、
マクロの中から別のマクロを呼び出したときに、
同じ場所に上書きしてしまうかもしれません。
こういう場合は、マクロ内でローカルなメモリ、
つまりローカル変数を使いたいところです。
結局マクロというのは呼ばれるたびに展開されるわけなので、
その都度メモリを適切に割り振ってやれば良いのですが、
これは、意外と単純な仕組みで実現できます。
; ローカル変数用に使う領域の定義
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
実行時に動的にメモリを確保しているわけじゃなくて、
あくまでもマクロ展開時に割り当てているので、
実行時の動作は普通にアドレスを直接記述したのと同じです。
ただローカル変数といってもマクロ内でローカルなだけなので、
サブルーチンや割り込みのことまで考えると、
・マクロの中からサブルーチンを呼び出さない
・割り込みの時はローカル変数領域全体を退避する
・あるいは割り込み処理ではローカル変数を使わない
とかの対策が必要になります。
登録:
投稿 (Atom)