- •3.11.1 Команды пересылки данных
- •Команды пересылки общего назначения
- •Xchg приемник, источник
- •Команды загрузки адресных значений
- •Команды обращения к стеку
- •Команды пересылки флагов
- •Команды ввода/вывода
- •In аккумулятор, порт
- •In аккумулятор, dx.
- •3.11.2. Арифметические команды
- •Типы арифметических данных
- •Команды инкрементирования и декрементирования
- •Inc приемник
- •Команды сложения и вычитания
- •Команды расширения знака
- •Команды умножения и деления
- •Imul источник.
- •Команды десятичной коррекции
- •Сложение в bdc-формате
- •Вычитание в bcd-формате
- •Сложение в ascii-формате
- •Вычитание в ascii-формате
- •Умножение в ascii-формате
- •Деление в ascii-формате
- •3.11.3 Логические команды
- •Команды логических операций
- •Команды сравнения
- •Команды сдвигов
- •Команды логических сдвигов
- •Команды арифметических сдвигов
- •Команды циклических сдвигов
- •3.11.4. Команды передачи управления
- •Команды безусловных переходов
- •Команды условных переходов
- •Команды перехода по состоянию арифметических флагов
- •Команды перехода по соотношению между числами
- •Команды перехода по состоянию регистра cx
- •Команды управления циклами
- •Команды для организации подпрограмм
- •Команды прерываний
- •3.11.5. Команды обработки строк
- •Строковые примитивы
Команды для организации подпрограмм
Подпрограмма (процедура) представляет собой совокупность команд, которая, располагаясь в памяти однократно, может быть исполнена сколь угодно раз в любом месте программы. Для использования подпрограмм необходимы команды для их вызова из текущей точки программы и команды для возврата из них в точку вызова. Очевидно, что для обеспечения корректного возврата необходимо сохранять адрес текущей точки программы. Этот адрес называется адресом возврата, и он автоматически сохраняется в стеке при вызове процедуры. При возврате из процедуры адрес возврата извлекается из стека и загружается в регистрыуказатели адреса команды, что обеспечивает возврат в точку вызова. Все эти функции выполняются двумя командами: 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).