Читать «Assembler. Программирование на языке ассемблера IBM PC» онлайн - страница 144

Unknown Author

Рассмотрим конкретный пример. Опишем макрос, вычисляющий остаток от деления одного натурального числа на другое с помощью вычитания:

MD MACRO Rl,R2    ;rl:=rl mod r2 (rl,r2 - регистры, без знака)

LOCAL М,М1

М: CMP R1,R2    ;;while rl>=r2 do rl:=rl-r2

JB Ml SUB R1,R2 JMP M

Ml:

ENDM

и предположим, что в последний раз макрогенератор использовал для специмен номер 0016. Тогда два очередных обращения к макросу MD будут обработаны следующим образом:

Rl—ьАХ, R2->BX

??0017: СМР АХ,ВХ

MD АХ,ВХ

М-»??0017, М1-»??0018

JB ??0018 SUB АХ,ВХ JMP ??0017

R1->CX, R2->DX

??0018:

??0019: CMP CX,DX

MD CX,DX

M->??0019, Ml-»??001A

JB ??001A SUB CX,DX JMP ??0019

??001A:

Таким образом, в разных макрорасширениях появляются разные метки, и тем самым проблема с одинаковыми метками снимается.

Отметим, что директиву LOCAL можно указывать только после директивы MACRO (но зато любое число раз) и нигде более и что директива LOCAL не переносится в макрорасширение. Кроме того, следует учитывать, что специмена ??0017 и т. п. - это обычные имена, и, вообще говоря, мы можем их использовать сами, однако в силу их особой роли не рекомендуется применять эти имена в ином качестве.

113.8.    Директива EXITJVI

Рассмотрим еще одну директиву макроязыка:

, EXITM

У этой директивы нет операндов. Ее можно использовать только внутри макроопределений и блоков повторения, т. е. внутри конструкций макроязыка, оканчивающихся директивой ENDM. Встретив директиву EXITM, макрогенератор завершает обработку ближайшего объемлющего макроопределения или блока повторения.

Например, при макроопределении

a macro к

REPT К

DB О

EXITM

ENDM

DW ?

ENDM

макрокоманда A 5 будет заменена на следующий текст:

DB О DW ?

Здесь макрогенератор, создавая первую копию тела блока повторения, перенесет предложение DB 0 в макрорасширение, а затем, встретив EXITM, полностью завершит обработку этого блока, но не покинет тело макроса - он "перескочит” за ближайшую директиву ENDM, т. е. на предложение DW ?.

Более содержательные примеры на директиву ЕХПМ будут приведены позже (они требуют знания условных директив). Пока лишь отметим, что эта директива используется тогда, когда при выполнении некоторого условия надо досрочно (не доходя до ENDM) прекратить макроподстановку или "раскрутку" блока повторения.

113.9.    Переопределение и отмена макросов

В отличие от других объектов программы на ЯА, макросы можно переопределить или уничтожить.

Если в тексте программы описать макрос с именем, которым ранее был обозначен другой макрос, то с этого момента прежний макрос считается уничтоженным, а новый макрос - действующим. Например:

A MACRO X INC X ENDM A CX

INC CX

A MACRO Y,Z

CMP Y,0 JE Z ENDM A BH,EQ

CMP BH,0 JE EQ

Макрос можно и просто уничтожить, не определяя новый макрос с тем же именем, для чего надо воспользоваться следующей директивой: