Иллюстрированный самоучитель по SVGA

Часто используемые в примерах имена

При оформлении макросов используются специальные директивы. Текст любого макроопределения начинается директивой macro, перед ней указывается имя макроса, а после нее, в той же строке, список аргументов, если таковые имеются, в данном примере это reg.

Другая, часто используемая директива – endm. В зависимости от контекста она указывает конец макроопределения или оператора, что и показано в примере 2.12.

Тела макроопределений примера 2.12 состоят из директивы повторения irp. После нее, в той же строке, указываются параметр г и имя списка аргументов, заключенное в угловые скобки. Оно должно совпадать с именем, указанным в директиве macro. В следующей строке записывается повторяемая команда, один из операндов которой г соответствует параметру директивы irp.

В общем случае тело директивы irp может состоять из нескольких команд или содержать другие директивы, поэтому нужен признак конца директивы endm.

Обнаружив в тексте программы макроопределение, Макроассемблер проверяет его синтаксис и запоминает имя и текст, не включая его в тело задачи. Исполнение макроопределения (вставка команд в тело задачи) будет производиться при каждом макровызове.

Параметры макровызова

Макровызовы или макрокоманды – это вставка текста макроопределения в нужных местах программы с подстановкой конкретных параметров, если они имеются. Для макроопределений примера 2.12 макровызов состоит из имени PushReg или PopReg и списка регистров, заключенного в угловые скобки. Угловые скобки позволяют использовать запятые между именами регистров, входящих в список.

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

В частности, при вызове макроопределений примера 2.12 директива irp повторяется столько раз, сколько имен содержит список reg. Название каждого имени выбирается из списка и подставляется в команду push или pop вместо параметра r.

В макроопределениях примера 2.12 разнообразие имен не ограничено явно, допустимо указание любых величин, которые могут быть операндами команд push и pop. Ими могут быть не только имена 16 – и 32-разрядных регистров, но и имена переменных, кроме того, команда push может сохранять в стеке значения констант (непосредственное указание сохраняемой величины). Все эти величины можно использовать в макровызове. Например, во многих подпрограммах будет использоваться такой вариант макровызовов:

PushReg <fs, gs, Cur_win> и PopReg <Cur_win, gs, fs>

Обратите внимание, имена в списках PushReg и PopReg расположены в обратном порядке, поскольку работа со стеком организована по принципу "последнее записанное – первое считанное".

Альтернативным способом сохранения группы регистров в стеке и восстановления их оттуда одной командой являются операции pusha и рора, не имеющие параметров. Их исполняют все модели микропроцессоров, кроме Intel 8086. Эти операции сохраняют в стеке или восстанавливают из него регистры в таком порядке:

PUSHA › ах, ex, dx, bx, sp, bp, si, di.
РОРА › di, si, bp, sp, bx, dx, ex, ax.

Начиная с модели Intel 80386, микропроцессоры поддерживают операции pushad и popad, также не имеющие параметров. Они сохраняют в стеке или восстанавливают из него 32-разрядные регистры в таком порядке:

PUSHAD › eax, ecx, edx, ebx, esp, ebp, esi, edi.
POPAD › edi, esi, ebp, esp, ebx, edx, ecx, eax.

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

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.