Вызов подпрограммы выполняется командой 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