Автор неизвестен - Руководство по препроцессору FASM
Название: | Руководство по препроцессору FASM | |
Автор: | Автор неизвестен | |
Жанр: | Самиздат, сетевая литература, Учебники и самоучители по компьютеру, Литература ХXI века (эпоха Глобализации экономики), Assembler | |
Изадано в серии: | неизвестно | |
Издательство: | неизвестно | |
Год издания: | - | |
ISBN: | неизвестно | |
Отзывы: | 1 комментарий | |
Рейтинг: | ||
Поделись книгой с друзьями! Помощь сайту: донат на оплату сервера |
Краткое содержание книги "Руководство по препроцессору FASM"
Аннотация к этой книге отсутствует.
Читаем онлайн "Руководство по препроцессору FASM". [Страница - 4]
behind?00000001:
call behind?00000002
db 'bbbbbbbb', 0
behind?00000002:
call something
Заметьте, Вы не сможете напрямую обратиться к метке содержащей ? так как это специальный символ в FASM, поэтому он и используется в локальных метках. К примеру, aa?bb рассматривается как идентификатор aa, специальный символ ? и идентификатор bb.
Если Вам нужно несколько локальных меток — не проблема, их можно указать в одной директиве LOCAL, разделив запятыми ,:
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. Оператор `
Существует оператор, преобразующий идентификатор в символьную строку. Он так же может быть использован только внутри макросов:macro proc name
{
name:
log `name ;log - макрос, принимающий параметр-строку
}
proc DummyProc
получим:
DummyProc:
log 'DummyProc'
Пример посложнее, с использованием #
macro proc name
{
name:
log 'начинается подпрограмма: '#`name
}
proc DummyProc
retn
proc Proc2
retn
будет:
DummyProc:
log 'начинается подпрограмма: DummyProc'
retn
Proc2:
log 'начинается подпрограмма: Proc2'
retn
6. Макросы с групповыми аргументами
6.1. Определение макросов с групповым аргументом
У макросов могут быть так называемые групповые аргументы. Это позволяет использовать переменное количество аргументов. При определении макроса, групповой аргумент заключается в квадратные скобочки [ и ]:Синтаксис:
macro name arg1, arg2, [grouparg]
{
; тело макроса
}
Среди аргументов в определении макроса, групповой аргумент должен быть последним. Групповой аргумент может содержать несколько значений:
macro name arg1,arg2,[grouparg] {}
name 1,2,3,4,5,6
В этом примере значение arg1 будет 1, arg2 — 2, а grouparg — 3,4,5,6.