Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Микропроцессорные системы (книга Комаров) / Программирование на Ассемблере (ч 2).doc
Скачиваний:
155
Добавлен:
08.03.2015
Размер:
380.93 Кб
Скачать

Команды для организации подпрограмм

Подпрограмма (процедура) представляет собой совокупность команд, которая, располагаясь в памяти однократно, может быть исполнена сколь угодно раз в любом месте программы. Для использования подпрограмм необходимы команды для их вызова из текущей точки программы и команды для возврата из них в точку вызова. Очевидно, что для обеспечения корректного возврата необходимо сохранять адрес текущей точки программы. Этот адрес называется адресом возврата, и он автоматически сохраняется в стеке при вызове процедуры. При возврате из процедуры адрес возврата извлекается из стека и загружается в регистрыуказатели адреса команды, что обеспечивает возврат в точку вызова. Все эти функции выполняются двумя командами: CALL и RET.

Команда CALL обеспечивает вызов подпрограмм. При этом вызов может осуществляться по прямому и косвенному адресу.

Команда прямого вызова записывается в формате:

CALL Name

и передает управление процедуре с именем Name. В качестве имени Name может использоваться любая метка или имя процедуры, введенное ее описанием с помощью директив PROC и ENDP (см. раздел 3.12). В зависимости от положения имени Name относительно команды CALL может совершаться ближний или дальний вызов процедур.

Формат CALL Name соответствует ближнему вызову (тип NEAR), когда команда CALL и команда, помеченная именем Name, находятся в одном сегменте программного кода. В этом случае машинный код команды CALL содержит два байта для хранения дистанции disp16 до имени Name. При выполнении такой команды в качестве адреса возврата в стеке сохраняется лишь содержимое регистра IP, а затем вычисляется и записывается в него начальный адрес (IP)+disp16(Name), что и соответствует ближнему вызову указанной процедуры.

В случае, если команда CALL и имя Name находятся в различных сегментах программного кода, то вызов является дальним (тип FAR). Для выполнения дальнего вызова команда в общем случае записывается в виде CALL FAR PTR Name. В машинном коде этой команды находится полный логический адрес точки назначения в формате segment:offset. При выполнении такой команды CALL в качестве адреса возврата в стеке сохраняется содержимое регистров CS:IP, а затем в них записывается адрес Name, что и соответствует дальнему вызову указанной процедуры.

Пример 3.99:

; Прямой вызов подпрограммы

CALL Delay ; Ближний прямой вызов подпрограммы Delay

CALL FAR PTR Time ; Дальний прямой вызов подпрограммы Time

Команда косвенного вызова подпрограмм записывается в формате:

CALL источник

и вызывает процедуру по адресу, являющемуся содержимым операнда-источника. В качестве источника могут использоваться 16-битный РОН или ячейка памяти, адресуемая любым способом. Если адрес вызова задается регистром или словом в памяти, то команда CALL выполняет ближний косвенный вызов. Если адрес перехода задается двойным словом в памяти, то выполняется дальний косвенный вызов. При этом содержимое младшего слова указанного двойного слова загружается в регистр IP, а старшего  в регистр CS.

Пример 3.100:

; Косвенные вызовы подпрограмм

CALL BX ;Ближний косвенный вызов по адресу (BX)

CALL WORD PTR [BX] ;Ближний вызов по ячейке памяти ((BX))

CALL Beta ;Дальний вызов по ячейке памяти (Beta DD ?)

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

Команда RET не имеет операндов. Она извлекает из стека адрес возврата. Если процедура имеет тип NEAR, то RET извлекает из стека одно слово и загружает его в указатель команд IP, что и обеспечивает внутрисегментный возврат. Если процедура имеет тип FAR, то команда RET извлекает из стека два слова и помещает их в регистры CS, IP, что и обеспечивает межсегментный возврат.

В команде RET допускается указывать непосредственное 16-битное значение, интерпретируемое как целое без знака, то есть она может записываться в виде:

RET число.

Эта команда выполняется идентично обычной RET, но после восстановления адреса возврата указанное число прибавляется к указателю стека SP, то есть (SP)=(SP)+число. Это используется для удаления входных параметров из стека при стековом способе передачи параметров в подпрограмму (см.подраздел 3.12).