, разделив запятыми
>,
:
>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