Руководство по препроцессору FASM (Неизвестен) - страница 6

, разделив запятыми >,:

>macro pushstr string ; делает то же, что и предыдущий макрос

>{

> local addr, behind

>  push addr

>  jmp behind

> addr db string,0

> behind:

>}

Всегда хорошо бы начинать все локальные метки макросов с двух точек >.. — это значит, что они не будут менять текущую глобальную метку. К примеру:

>macro pushstr string

>{

> local behind

>  call behind

>  db string, 0

> behind:

>}

>MyProc:

> pushstr 'aaaa'

>.a:

будет преобразовано в:

>MyProc:

> call behind?00000001

> db 'aaaa', 0

>behind?00000001:

>.a:

в результате получим метку >behind?00000001.a вместо >MyProc.a. Но если в примере выше >behind заменить на >..behind, текущая глобальная метка не изменится и будет определена метка >MyProc.a:

>macro pushstr string

>{

> local ..behind

>  call ..behind

>  db string,0

> ..behind:

>}

>MyProc:

> pushstr 'aaaa'

>.a:

5.4. Оператор объединения #

У макроязыка FASMа есть ещё одна возможность — манипуляции с идентификаторами. Делается это оператором >#, который объединяет два идентификатора в один. К примеру, >a#b становится >ab, а >aaa bbb#ccc ddd>aaa bbbccc ddd.

Оператор ># может быть использован только внутри тел макросов, а объединение символов происходит после замены аргументов макроса параметрами. Так что его можно использовать для создания новых идентификаторов из переданных в макрос параметров:

>macro string name, data

>{

> local ..start

> ..start:

> name db data,0

> sizeof.#name = $ —..start

>}

>string s1,'нудные макросы'

>string s2,<'а вот и я',13,10,'заставлю тебя их видеть во сне'>

получим:

>..start?00000001:

>s1 db 'нудные макросы',0

>sizeof.s1 = $ —..start?00000001

>..start?00000002:

>s2 db 'а вот и я',13,10,'заставлю тебя их видеть во сне',0

>sizeof.s2 = $ —..start?00000002

так что для всех строк, создаваемых этим макросом будет определён идентификатор >sizeof.имя строки, равный количеству байт строки.

Оператор ># способен так же объединять символьные строки:

>macro debug name

>{

> db 'name: '#b,0

>}

>debug '1'

>debug 'foobar'

>будет:

>db 'name: 1',0

>db 'name: foobar',0

Это полезно при передаче аргументов из макроса в макрос:

>macro pushstring string

>{

> local ..behind

>  call ..behind

>  db string,0

> ..behind:}

>macro debug string

>{

> push MB_OK

> push 0 ;empty caption

> pushstring 'debug: '#string ;принимает один аргумент

> push 0                      ;нет окна-предка

>  call [MessageBox]

>}

Обратите внимание, нельзя использовать ># совместно с идентификаторами, определёнными >local, так как >local обрабатывается препроцессором раньше, чем >#. Из-за этого подобный код работать не будет:

>macro a arg

>{

> local name_#arg

>}

>a foo

5.5. Оператор `

Существует оператор, преобразующий идентификатор в символьную строку. Он так же может быть использован только внутри макросов: