第17章
繰り返しブロック
繰り返しブロック(repeat block)は、TATARAがその場で繰り返す行のまとまりです。その場で定義して使う、名前のないマクロのように働きます。REPTは指定した回数だけ、IRPはリストの項目ごとに1回ずつ、IRPCはテキストの文字ごとに1回ずつ、その行を繰り返します。
3つとも、マクロと同じようにENDMで終わり、本体、LOCAL、EXITMについては16章の規則に従います。
17.1 REPT
REPTのあとには回数を書きます。ENDMまでの行が、その回数だけアセンブルされます。
cseg here: rept 3 nop endm dw here
here: rept 3 nop endm 0000' 00 + nop 0001' 00 + nop 0002' 00 + nop 0003' 00 00 dw here
リスティングには、書いたとおりのブロックに続いて、それぞれの回が、マクロの展開と同じように+の印付きで表示されます。REPTの行のラベルは、最初の回の始まりを示します。hereは0000hです。
回数にはどんな式でも書けますが、TATARAはブロックの行を読む前にそれを計算するので、すでにわかっている数でなければなりません。あとで定義される名前を使うと、TATARAはundefined symbol in an expression.と表示して止まり、コード・セグメントのラベルのようなリロケータブルな値を使うと、8章のリロケーション・エラーで止まります。回数が0なら、何もアセンブルされません。
DEFL(12章)がいちばん役に立つのは、繰り返しブロックの中です。DEFLで定義した名前には回ごとに新しい値を与えられるので、回数を数えられます。
n defl 0 rept 4 db n n defl n+1 endm
0000' 00 + db n 0001' 01 + db n 0002' 02 + db n 0003' 03 + db n
リスティングにはそれぞれの行が書いたとおりdb nと表示され、バイトはその回でのnの値を示しています。
17.2 IRP
IRPのあとには、パラメーター名、コンマ、山かっこで囲んだ項目のリストを書きます。ブロックは項目ごとに1回ずつ、パラメーターをその項目に置き換えてアセンブルされます。
irp x,<1,2,4,8> db x endm
0000' 01 + db 1 0001' 02 + db 2 0002' 04 + db 4 0003' 08 + db 8
項目は、マクロの引数と同じ規則に従います(16.2節)。コンマを含む項目は、それ自身の山かっこで囲みます。また、%を付けると、テキストの代わりに値が渡されます。
five equ 5 irp s,<'ab',<'c,d'>> db s endm irp v,<five*2,%five*2> db '&v' endm
0005' 61 62 + db 'ab' 0007' 63 2C 64 + db 'c,d' 000A' 66 69 76 65 + db 'five*2' 000E' 2A 32 + 0010' 31 30 + db '10'
リストを囲む山かっこは省略できます。irp x,1,2,3はirp x,<1,2,3>と同じです。空のリストirp x,<>では、パラメーターが空のまま1回実行されます。
IRPがいちばん役に立つのは、マクロの中で、それ自体がリストである引数に対して使うときです。
bytes macro list irp b,<list> db b endm endm
bytes <10,20,30> 0000' 0A + db 10 0001' 14 + db 20 0002' 1E + db 30
17.3 IRPC
IRPCのあとには、パラメーター名、コンマ、テキストを書きます。ブロックはテキストの文字ごとに1回ずつ、パラメーターをその文字に置き換えてアセンブルされます。マクロと同じように、文字列の中のパラメーターには&が必要です(16.3節)。
irpc c,TATARA db '&c' endm
0000' 54 + db 'T' 0001' 41 + db 'A' 0002' 54 + db 'T' 0003' 41 + db 'A' 0004' 52 + db 'R' 0005' 41 + db 'A'
空白やコンマも含めて、すべての文字が数えられます。irpc c,<A B,C>は、A、空白、B、コンマ、Cの 5回になります。山かっこはテキストに空白を入れるときにだけ必要で、テキストには含まれません。空のテキストirpc c,<>では、1回も実行されません。IRPCのテキストでは、!と%に特別な意味はありません。
17.4 LOCAL、EXITM、入れ子
LOCALは、繰り返しブロックでもマクロと同じように働き、回ごとに別の名前を与えます。
rept 2 local skip jr skip nop skip: endm
0000' 18 01 + jr ??0000 0002' 00 + nop 0003' 18 01 + jr ??0001 0005' 00 + nop
LOCALがなければ、2回目でskipをもう一度定義することになります。ラベルだけの行はバイトを作らないので、展開には表示されません。
EXITMは、まだ実行していない回も含めて、ブロック全体を終わらせます。次のブロックは10回実行されるはずですが、3回で止まります。
n defl 0 rept 10 if n eq 3 exitm endif db n n defl n+1 endm db 0ffh
0000' 00 + db n 0001' 01 + db n 0002' 02 + db n 0003' FF db 0ffh
繰り返しブロックは、ほかの繰り返しブロックやマクロの中に入れることができ、それぞれのENDMはいちばん内側のものを終わらせます。マクロの展開やインクルード・ファイルと合わせて、16段まで重ねられます(16.7節)。
17.5 メッセージ
繰り返しブロックについてのメッセージを、それぞれの原因となる行とともに表17.1に示します。繰り返しブロックの中でエラーが起きると、メッセージのあとの経路にはブロックがa repeat blockと表示されます。