Вызов подпрограмм

Вызов подпрограммы выполняется командой call. Вызов также бывает ближний или дальний. При ближнем вызове в стеке запо­минается текущее значение регистра IP, используемое затем командой ret (ближней) для возврата в точку вызова. При дальнем вызове в стек заносится также значение сегментного регистра CS, что позволяет команде ret (дальней) выполнить возврат в другой сегмент.

Тип вызова определяется типом операнда команды. Если в ка­честве операнда указано имя подпрограммы, то тип FAR или NEAR выбирается в зависимости от описания подпрограммы. Если в ка­честве операнда используется слово или двойное слово памяти, то выполняется косвенный, соответственно ближний или дальний вызов подпрограммы по адресу, хранящемуся в памяти. При этом в двойном слове младшее слово содержит смещение, старшее слово - сегмент из адреса подпрограммы.

Например. Пусть в сегменте данных описаны переменные:

FADDR dd ?
NADDR dw ?

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

FPROC proc FAR
. . .
FPROC endp
NPROC proc
. . .
NPROC endp

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

call FPROC ;Дальний прямой вызов п/п FPROC
call NPROC ;Ближний прямой вызов п/п NPROC
call FADDR ;Дальний прямой вызов п/п, чей адрес - в FADDR
call NADDR ;Ближний прямой вызов п/п, чей адрес - в NADDR
call BX ;Ближний косвенный вызов п/п, чей адрес - в рег.BX
call word ptr [BX] ;Ближний косвенный вызов п/п, чей адрес -
; в слове, адрес которого - в BX
call dword ptr [BX] ;Дальний косвенный вызов п/п, чей адрес -
; в двойном слове, адрес которого - в BX