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

Учет особенностей компилятора

Директива вызова процедуры

Для вызова процедур, ориентированных на передачу параметров в стеке, предназначена специальная директива:

Invoke имя_процедуры [, список_параметров]

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

Если в списке указано имя переменной, то процедуре передается ее значение. Если указано имя регистра, то передается его содержимое. Для передачи содержимого пары регистров между их именами дважды указывается символ "двоеточие". Например, если формальный параметр описан как двойное слово и предназначен для передачи адреса, то в качестве фактического параметра можно указать пару регистров DS: – .si.

Для передачи адреса переменной перед ее именем указывается ключ ADDR. Если формальный параметр описан как двойное слово, то процедуре передается сегмент, в котором описана переменная и ее смещение (адрес) относительно начала сегмента. Если формальный параметр описан как слово, то процедуре передается только сегмент, в котором расположена переменная, в некоторых случаях это может пригодиться на практике.

При передаче адреса вместо имени переменной может быть указано выражение в форме, позволяющей Макроассемблеру однозначно определить адрес (смещение) переменной в сегменте, например, ADDR iinbuf+2.

При обработке директивы invoke Макроассемблер вставляет в объектный модуль группу команд, выполняющих размещение параметров в стеке, а после них команду вызова процедуры. Обычно результат подстановки в листинге отсутствует. Чтобы увидеть его в начале текста модуля, надо поместить директиву .Listaii (точка обязательна).

Последовательность записи параметров в стек зависит от имени, указанного в качестве Langtype в описании процедуры. Если указаны имена Basic, Fotran или Pascal, то параметры записываются в стек в порядке их перечисления в списке директивы invoke. Если же указаны имена С, Syscall или Stdcall, то параметры записываются в стек в обратном порядке (см. табл. В.3). Это обеспечивает соответствие способов записи и использования передаваемых в стеке параметров.

Вызов cnvindec

В качестве примера покажем, как может выглядеть вызов процедуры, описанной в примере В.7. Для этого в вызывающем модуле указывается следующая директива:

Invoke cnvindec, ADDR linbuf

Предполагается, что имя linbuf соответствует буферу, содержащему строку цифр в коде ASCII (см. раздел В.З). Если linbuf расположена в сегменте данных, то директива преобразуется в следующие команды:

push ds; запись содержимого ds
push offset linbuf; запись адреса linbuf
call cnvindec; вызов подпрограммы cnvindec

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

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

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