はじめに
GNU Assembler (gas) で.macroを使用した際、普通にラベルを定義するとうまくできなかったので、解決方法をメモ..
問題点
マクロを使い、ラベルを定義、マクロを2回以上呼び出すとラベルが重複しているとエラーが発生する。
(例)
.macro wait_status addr exp_data
mov exp_data, r10
mov addr, r11
WAIT:
ld.w 0x0[r11], r12
and exp_data, r12
cmp r10, r12
bnz WAIT
.endm
MAIN:
wait_status 0xfff0 , 0x0
wait_status 0xfff4 , 0x0
解決方法①
ローカルラベルを使用する。
(例)
.macro wait_status addr exp_data
mov exp_data, r10
mov addr, r11
1:
ld.w 0x0[r11], r12
and exp_data, r12
cmp r10, r12
bnz 1b
.endm
MAIN:
wait_status 0xfff0 , 0x0
wait_status 0xfff4 , 0x0
#ローカルラベル内で、同一ローカルラベルを使用したマクロを呼び出して、マクロを抜けた後に br 1b とかするとマクロの関数に戻るんですかね..?こわい..
解決方法②
\@を使用する。
(例)
.macro wait_status addr exp_data
mov exp_data, r10
mov addr, r11
WAIT\@:
ld.w 0x0[r11], r12
and exp_data, r12
cmp r10, r12
bnz WAIT\@
.endm
MAIN:
wait_status 0xfff0 , 0x0
wait_status 0xfff4 , 0x0
番号を付与してくれるみたいです。WAIT1,WAIT2みたいに!
参考:
https://sourceware.org/binutils/docs/as/Macro.html
まとめ
ぜひ使ってみてください。
他には引数でラベルを与えるとかあるみたいですが、微妙なので使いませんでした..