Директива ARG определяет аргументы, передаваемые в процедуру. Ее применение позволяет обращаться к аргументам по их именам, а не смещениям относительно содержимого bp. К примеру, если в начале рассматриваемой нами процедуры на ассемблере asmproc задать директиву ARG в виде arg kol:word,y:word,х:word,chr:byte, то к аргументам процедуры можно будет обращаться по их именам, без подсчета смещений. Ассемблер сам выполнит всю необходимую работу. В этом можно убедиться, запустив программу в отладчике. Обратите внимание: порядок следования аргументов в директиве arg является обратным порядку их следования в описании . процедуры (строка procedure asmproc(ch: char: x, у, kol: integer); external; в программе на Pascal). Процедура asmproc с использованием директивы arg представлена в листинге 3.
После того как решена проблема передачи аргументов в процедуру и выполнены все необходимые действия, возникает очередной вопрос - как правильно возвратить управление? При возврате управления в программу на Pascal нужно помнить, что соглашения этого языка требуют, чтобы вызываемые процедуры самостоятельно очищали за собой стек. Программа на ассемблере также должна удовлетворять этому требованию и заботиться об очистке стека перед своим завершением. Для этого необходимо составить эпилог.
Действия, выполняемые, кодом эпилога для связи Pascal - ассемблер:
1. Записать содержимое bp в sp командой mov sp, bp. Это действие восстанавливает в sp значение, которое было на момент входа в процедуру. Необходимость в этом действии возникает в том случае, если в процедуре производилась работа со стеком: В листинге 14.3 такой работы не было, поэтому код эпилога содержит только действия следующих пунктов.
2. Восстановить сохраненный в стеке регистр bp.
3. Удалить из стека переданные процедуре аргументы.
Для удаления из стека аргументов можно использовать различные способы:
h явно скорректировать значение sp, переместив указатель стека на необходимое количество байт в положительную сторону. Это - не универсальный способ, к тому же он чреват ошибками, особенно при частых модификациях программы;
hиспользовать в директиве arg после записи последнего аргумента операнд, состоящий из символа равенства "=" и идентификатора, указанного за ним в следующей синтаксической конструкции:= идентификатор. В этом случае TASM при обработке директивы arg подсчитает количество байт, занятых всеми аргументами, и присвоит их значение идентификатору. В нашем случае директиву arg можно определить так: arg ch:byte;x:word;y:word;ko1:word=a_size. TASM после обработки данной директивы присвоит имени a_size значение 8 (байт). Это имя впоследствии нужно будет указать в качестве операнда команды ret:
ret a_size
Использование директивы arg (листинг 3).
{prg3.pas}
{Программа на Pascal, вызывающая процедуру на ассемблере, полностью совпадает с листингом 1}