Команды передачи управления

Эти команды нарушают естественный порядок выполнения команд посредством загрузки в командный счетчик адреса команды, к которой осуществляют переход. Решение о том, какая команда должна выполняться следующей может быть:

1) безусловным – из данной точки программы необходимо передать управление не следующей команде, а другой, которая находится на некотором удалении т текущей;

2) условным – решение о том, какая команда будет выполняться следующей, принимается на основе анализа некоторых условий или данных.

Безусловные переходы.

Безусловные переходы связаны с использованием команды безусловного перехода и команд обращений к процедурам.

Команда безусловного перехода

Формат команды

JMP [Модификатор] адрес_перехода

Этой командой задаются внутрисегментные и межсегментные переходы.

Описание команды безусловного перехода для внутрисегментных переходов представлено в таблице 4.10.

Таблица 4.10 – Формат команды для внутрисегментных переходов

Вариант внутрисегментного перехода Мнемоника и формат команды Описание действия
Прямой короткий переход (расстояние от команды JMP до адреса перехода не превышает -128 или 127 байт) JMP SHORT OPR (IP) (IP) + 8- битное смещение, определяемое OPR
Прямой переход (на расстояние от 128 байт до 64 Кбайт) JMP [NEAR] OPR (IP) (IP) + 16- битное смещение, определяемое OPR
Косвенный переход (в команде указывается не сам адрес перехода, а место, где он находится) JMP OPR (IP) (EA), где EA- эффективный адрес, определяемый OPR

Формат команды для межсегментных переходов описан в таблице 4.11.

Таблица 4.11 – Формат команды для межсегментных переходов

Вариант межсегментного перехода Мнемоника и формат команды Описание действия
Прямой переход JMP FAR PTR OPR (CS) начальный адрес сегмента, определяемого OPR (IP) смещение в сегменте из OPR
Косвенный переход JMP OPR (IP) (EA), где EA- эффективный адрес, определяемый OPR (CS) (EA + 2), где EA- эффективный адрес из OPR

Тип перехода определяется типом операнда. Межсегментные передачи управления реализуются только командами безусловных переходов. Не модифицируются все флажки условий. Что касается режимов адресации, то во внутрисегментных прямых переходах применяется относительный режим, в межсегментных прямых переходах - прямой режим. В косвенных переходах не допускается непосредственный режим, а в межсегментных косвенных переходах должна адресоваться память.

Обращение к процедурам

Процедура (подпрограмма) – это группа команд для решения конкретной подзадачи, обладающая средствами получения управления из точки вызова задачи более высокого уровня и возврата управления в эту точку.

Другими словами, это правильным образом оформленная совокупность команд, которая, будучи однократно описана, при необходимости может быть вызвана в любом месте программы.

Описание процедуры состоит из заголовка, тела и конца процедуры:

имя_процедуры PROC [расстояние] – заголовок процедуры

Команды передачи управления - student2.ru

команды, директивы ассемблера - тело процедуры

Команды передачи управления - student2.ru ret

имя_процедуры ENDP - конец процедуры

Имя процедуры – это идентификатор (метка), по которому происходит обращение к процедуре из основной программы или другой процедуры. Необязательный параметр [расстояние] характеризует возможность обращения к процедуре из другого сегмента кода. Моет принимать значения: NEAR – для процедур ближнего вызова (описание процедуры находится в том же самом сегменте кода, что и основная программа) и FAR – для процедур дальнего вызова (описание процедуры находится в другом сегменте кода). По умолчанию этот параметр равен NEAR.

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

1) в начале программы (до первой исполняемой команды);

c_s segment

assume cs:c_s

Pr1 proc near

Ret

P1 endp

begin: ;начало программы

end begin

2) в конце программы (после команды корректного завершения работы и возвращения управления операционной системе- ОС);

c_s segment

assume cs:c_s

begin:

mov ah, 4ch

int 21h ;корректное завершение работы и передача управления ОС

P1 proc near

Ret

P1 endp

c_s ends

end begin

3) внутри тела программы или другой процедуры (должен быть предусмотрен обход процедуры с помощью оператора JMP);

c_s segment

assume cs:c_s

begin:

jmp m1

P1 proc near

Ret

P1 endp

m1: …

mov ah, 4ch

int 21h ;корректное завершение работы и передача управления ОС

c_s ends

end begin

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

Специальный механизм вызова процедур, который поддерживается командами CALL и RET, позволяет сохранять информацию о состоянии программы в точке вызова процедуры. Команда CALL осуществляет вызов процедуры, сохраняя предварительно в стеке адрес возврата – адрес команды, следующей после команды CALL. При выполнении команды CALL осуществляется передача управления по адресу с символическим именем имя_процедуры.

Формат команды CALL:

CALL [Модификатор] имя_процедуры

Модификатор может принимать значения NEAR или FAR, для обращения к процедурам ближнего или дальнего вызовов, соответственно.

Команда RET считывает из стека адрес возврата и загружает его в регистр IP/EIP или регистры CS и IP/EIP, возвращая тем самым управление на команду, следующую в программе или другой процедуре за командой CALL.

Для процедур ближнего вызова адрес возврата полностью определяется содержимым регистра IP/EIP, а для процедур дальнего вызовы – содержимым дух регистров: CS и IP/EIP. При этом команда CALL запоминает в стеке сначала значение регистра CS, а затем значение регистра IP/EIP. Важно также отметить, что одна и та же процедура не может быть одновременно и процедурой ближнего вызова, и процедурой дальнего вызова.

Примечание:при использовании процедур программа должна обязательно содержать сегмент стека для обеспечения корректной обработки процедур. Тогда, в общем случае, программа будет иметь три сегмента: сегмент стека, сегмент данных и сегмент кода.

Условные переходы

В этих командах, также как и в командах безусловного перехода, нарушается естественный порядок выполнения команд. Но в условном переходе замена содержимого программного счетчика зависит от условия или от состояния флагов (без AF). Команды условно перехода, проверяющие некоторое условие, используются только совместно с командой сравнения CMP, рассмотренной выше, которая задает значение условия перехода. Команды условного перехода, работающие с флагами условий, могут использоваться как совместно с командой CMP (некоторые), которая модифицирует флаги, так и с другими командами, изменяющими флаги (все).

Команды условного перехода и их формат представлены в таблице 4.12.

Таблица 4.12 – Формат команд условного перехода

Название команды Мнемоника и формат команды Критерий условного перехода (в CMP) Значение флагов для перехода
Перейти, если равно JE OPR OPR1 = OPR2 ZF = 1
Перейти, если не равно JNE OPR OPR1 <> OPR2 ZF = 0
Перейти, если ниже (меньше)/ не выше или равно (без знака) JB/ JNAE OPR OPR1 < OPR2 CF = 1
Перейти, если не ниже (меньше)/ выше или равно (без знака) JNB/ JAE OPR OPR1 >= OPR 2 CF = 0
Перейти, если ниже или равно/ не выше (без знака) JBE/ JNA OPR OPR1 <= OPR2 CF = 1 или ZF = 1
Перейти, если не ниже или равно/ выше (больше) (без знака) JNBE/ JA OPR OPR1 > OPR2 CF = 0 и ZF = 0
Перейти, если меньше/ не больше (со знаком) JL/ JNGE OPR OPR1 < OPR2 SF <> OF
Перейти, если не меньше/ больше или равно (со знаком) JNL/ JGE OPR OPR1 => OPR2 SF = OF
Перейти, если меньше или равно/ не больше (со знаком) JLE/ JNG OPR OPR1 <= OPR2 SF <> OF или ZF = 1
Перейти, если не меньше или равно/ больше (со знаком) JNLE/ JG OPR OPR1 > OPR2 SF = OF и ZF=0  
Продолжение таблицы 4.12
Перейти, если ноль JZ OPR [OPR1 = OPR2] ZF = 1
Перейти, если не ноль JNZ OPR [OPR1 <> OPR2] ZF = 0
Перейти, если знак установлен JS OPR [OPR1 < OPR2] SF = 1
Перейти, если знак сброшен JNS OPR [OPR1 > OPR2] SF = 0
Перейти, если есть переполнение   JO OPR - OF = 1
Перейти, если нет переполнения JNO OPR - OF = 0
Перейти, если паритет установлен JP OPR - PF = 1
Перейти, если паритет сброшен JNP OPR - PF = 0
Перейти, если перенос установлен JC OPR - CF = 1
Перейти, если перенос сброшен JNC - CF = 0

Если проверочное условие удовлетворяется, то действие этих команд заключается в следующем:

(IP) (IP)+ 8-битное смещение с расширением знака.

В противном случае программный счетчик не изменяется, и программа продолжается в естественном порядке. Не модифицируются флажки условий. Режимы адресации - относительно программного счетчика (IP). Операнд OPR должен быть в пределах от-128 до127 байт от команды, находящейся за командой перехода.

Команды циклов

Циклы организуются для многократного повторения одной или нескольких команд программы или процедуры. Цикл можно организовать, используя команды условного и безусловного переходов, рассмотренных выше, а можно с помощью специальных команд. Формат команд представлен в таблице 4.13.

Команда LOOP и ее расширения позволяют организовывать циклы, подобные циклам for в языках высокого уровня.

Таблица 4.13 – Формат команд циклов

Название команды Мнемоника и формат команды Проверяемое условие
Зациклить LOOP OPR (ECX/ CX) <> 0
Зациклить, пока ноль или равно LOOPZ/ LOOPE OPR (ECX/ CX) <> 0 или ZF = 0
Зациклить, по не ноль или не равно LOOPNZ/ LOOPNE OPR (ECX/ CX) <> 0 или ZF=1
Переход по CX JCXZ OPR (ECX/ CX) = 0

За исключением команды JCXZ, которая не изменяет (ECX/ CX), производится (ECX/ CX)(ECX/ CX)-1, затем, если проверяемое условие удовлетворяется, (EIP/ IP)(EIP/ IP)+D8 с расширением знака; в противном случае (IP) не изменяется и программа продолжается в естественном порядке.

Не модифицируются все флажки условий. Режимы адресации - относительно IP. Операнд OPR должен быть меткой, которая находится в диапазоне от -128 до127 байт от команды, следующей за командой цикла.

Стековые команды

Организация стека

Стек – это область памяти, специально выделяемая для временного хранения данных программы. Для стека в структуре программы предусмотрен отдельный сегмент. Регистры процессора для работы со стеком были рассмотрены выше (в разделе 4.8).

Размер стека зависит от режима работы процессора и ограничивается значением 64 Кбайт в обычном режиме (или 4 Гбайт в защищенном режиме). В каждый момент времени доступен только один стек, начальный адрес сегмента которого содержится в регистре SS. Для перехода к другому стеку необходимо загрузить в SS его адрес. Запись и чтение данных в стеке осуществляется в соответствии с принципом LIFO (Last Input First Output - Последним Пришел Первым Ушел). По мере записи данных в стек он растет в сторону младших адресов памяти.

Концептуальная схема организации стека представлена на рисунке 4.2. Регистры SS, ESP/ SP и EBP/ BP используются комплексно, каждый из них имеет свое функциональное назначение. Регистр ESP/ SP всегда указывает на вершину стека, то есть содержит смещение относительно начала стека, по которому в стек был записан последний элемент. Для доступа к элементам не в вершине, а внутри стека используется регистр EBP/ BP – указатель базы кадра стека. Например, при входе в процедуру выполняется передача нужных параметров путем записи их в стек. Если процедура также использует стек, то доступ к этим параметрам становится проблематичным. Выход заключается в том, чтобы после записи параметров в регистр EBP/ BP записать адрес вершины стека ESP/ SP. Значение регистра ESP/ SP в дальнейшем будет изменяться, однако в регистре EBP/ BP хранится адрес, используя который , можно получить доступ к переданным параметрам.

Команды передачи управления - student2.ru Команды передачи управления - student2.ru

Рисунок 4.2 – Схема организации стека

Когда стек пуст, то значение регистра ESP/ SP равно адресу последнего байта сегмента (самому старшему адресу ячейки памяти в сегменте), выделенного под стек. Когда стек заполнен, то значение регистра ESP/ SP становится равным значению регистра SS, и дальнейшее добавление элементов невозможно. При помещении элементов в стек адрес вершины стека (содержимое регистра ESP/ SP) уменьшается (смещается в сторону меньших адресов), а при извлечении элементов из стека – увеличивается (смещается в сторону больших адресов).

Для работы со стеком предусмотрены специальные команды, формат которых представлен в таблице 4.14.

Таблица 4.14 – Формат стековых команд

Название команды Мнемоника и формат команды Описание действия
Включить в стек PUSH SRC (SP) (SP) – 2 ((SP + 1):SP) (SRC)
Извлечь из стека POP DST (DST) ((SP + 1):SP) (SP) (SP) + 2

Команда PUSH сначала уменьшает значение SP на 2, а затем по адресу (SP+1):SP записывает содержимое источника.

Команда POP сначала записывает содержимое из вершины стека (по адресу (SP+1):SP) по месту, указанному в DST, а затем увеличивает SP на 2.

В качестве операнда- источника SRC и в качестве операнда- приемника DST используются только регистры, кроме однобайтных и регистра CS.

Наши рекомендации