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

JMP операнд_ Безусловный переход_S0B6

JMP передает управление в другую точку программы, не сохраняя какой-либо

информации для возврата. Операндом может быть непосредственный адрес для пе­рехода (в программах используют имя метки, установленной перед командой, на которую выполняется переход), а также регистр или переменная, содержащая адрес,

В зависимости от типа перехода различают:

а переход типа short (короткий переход) - если адрес перехода находится в пре­делах -128...+127 байт от команды JMP; а переход типа near (ближний переход) - если адрес перехода находится в том же сегменте памяти, что и команда JMP;

□ переход типа far (дальний переход) - если адрес перехода находится в дру­гом сегменте. Дальний переход может выполняться и в тот же самый сегмент при условии, что в сегментной части операнда указано число, совпадающее с текущим значением CS;

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

При выполнении переходов типа short и^еат команда JMP фактически преоб­разовывает значение регистра EIP (или IP), изменяя тем самым смещение следу­ющей исполняемой команды относительно начала сегмента кода. Если операнд -регистр или переменная в памяти, то его показатель просто копируется в EIP, как если бы это была команда MOV. Если операнд для JMP - непосредственно ука­занное число, то его значение суммируется с содержимым EIP, приводя к относи­тельному переходу. В ассемблерных программах в качестве операнда обычно указывают имена меток, но на уровне исполняемого кода ассемблер вычисляет и записывает именно относительные смещения.

Выполняя дальний переход в реальном, виртуальном и защищенном режимах

(при переходе в сегмент с теми же привилегиями), команда JMP просто загружа­ет новое значение в EIP и новый селектор сегмента кода в CS, используя старшие 16 бит операнда как новое значение для CS и младшие 16 или 32 бит в качестве значений IP или EIP.

Команда

Назначение

Процессор

Jcc метка

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

' 8086

Это набор команд, выполняющих переход (типа short или near), если удовлет­воряется соответствующее условие, которым в каждом случае реально является состояние тех или иных флагов. Но, когда команда из набора Jcc используется сразу после СМР, условия приобретают формулировки, соответствующие отно­шениям между операндами СМР (см. табл. 7). Например, если операнды СМР были равны, то команда JE, выполненная сразу после СМР, осуществит переход. Операнд для всех команд из набора Jcc - 8-битное или 32-битное смещение отно­сительно текущей команды.

Слова «выше» и «ниже» в таблице относятся к сравнению чисел без знака; сло­ва «больше» и «меньше» учитывают знак.

Команды Jcc не поддерживают дальних переходов, поэтому, если требуется вы­полнить условный переход на дальнюю метку, необходимо использовать команду из набора Jcc с обратным условием и дальний JMP, как, например:

стр ах,О

jne locaM

jmp farjabel ; Переход, если АХ = 0.

local, 1:

Непривилегированные команды Таблица 7. Варианты команды Jcc

Код команды

Реальное условие

Условие для CMP

JA JBE

CF = 0 и ZF = 0

Если выше

Если не ниже и не равно

JAE JNB JNC

CF = 0

Если выше или равно Если не ниже Если нет переноса

JB

JNAE JC

CF= 1

ниже

Если не выше и но равно Если перенос

JBE JNA

CF = 1 или ZF = 1

Если ниже или равно Если не выше

JE JZ

ZF= 1

Если равно

Если ноль

JG

JNLE

ZF = 0 и SF = OF

Если больше

Если не меньше и не равно

JGE JNL

SF = OF

Если больше или равно

Если не меньше

JL

JNGE

SF 0 OF

Если меньше

Если не больше и не равно

JLE JNG

ZF=1 илиSF0 OF

Если меньше или равно

Если не больше

JNE JNZ

ZF = 0

Если не равно

Если не ноль

JNO

OF = 0

Если нет переполнения

JO

0F= 1

Если есть переполнение

JNP JPO

PF = 0

Если нет четности Если нечетное

JP JPE

PF= 1

Если есть четность

Если четное

JNS

SF = 0

Если нет знака

JS

SF= 1

Если есть знак

Команда

Назначение

Процессор

JCXZ метка JECXZ метка

Переход, если СХ - 0 Переход, если ЕСХ = О 8086 80386

Выполняет ближний переход на указанную метку, если регистр СХ или ЕСХ (для 1СХ7 и 1ЕСХ7 соответственно) равен нулю. Так же как и команды из серии ]сс, и не могут выполнять дальних переходов. Проверка равенства

СХ нулю, например, может потребоваться в начале цикла, организованного ко­мандой ЬООРЖ, - если в него войти с СХ = 0, то он будет выполнен 65 535 раз.

Команда

Назначение

Процессор

LOOP метка

Цикл 8086

Уменьшает регистр ЕСХ на 1 и выполняет переход типа short на метку (кото­рая не может быть дальше расстояния -128...+ 127 байт от команды ЮОР), если ЕСХ не равен нулю. Эта команда используется для организации циклов, в кото­рых регистр ЕСХ (или СХ при 16-битной адресации) играет роль счетчика. Так, в следующем фрагменте команда ADD выполнится 10 раз:

mov cx.OAh

loop_start:

add ax.cx

loop loop_start

Команда LOOP полностью эквивалентна паре команд

dec ecx jnz метка

Но LOOP короче этих двух команд на один байт и не изменяет значения флагов.

Команда

Назначение

Процессор

LOOPE метка

Цикл, пока равно

8086

LOOPZ метка

Цикл, пока ноль

8086

LOOPNE метка

Цикл, пока не равно

8086

LOOPNZ метка

Цикл, пока не ноль

8086

Все перечисленные команды уменьшают регистр ЕСХ на один, после чего вы­полняют переход типа short, если ЕСХ не равен нулю и если выполняется условие. Для команд и условием является равенство единице флага ZF, для

команд LOOPNE и LOOPNZ - равенство флага ZF нулю. Сами команды LOOPcc

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

DS.-SI в строку в E&DI (см. описание команд работы со строками), пока не кончится строка (СХ = 0) или пока не встретится символ с ASCII-кодом 13 (конец строки):

mov move_loop:

lodsb stosb

cmp al,13 loopnz move_loop

Команда

Назначение

Процессор

CALL операнд

Вызов процедуры

8086

Сохраняет текущий адрес в стеке и передает управление по адресу, указанно­му в операнде. Операндом может быть непосредственное значение адреса (метка в ассемблерных программах), регистр или переменная, содержащие адрес пере­хода. Если в качестве* адреса перехода указано только смещение, считается, что адрес расположен в том же сегменте, что и команда CALL. При этом, так же как и в случае с JMP, выполняется ближний вызов процедуры. Процессор помещает значение регистра EIP (IP при 16-битной адресации), соответствующее следую­щей за CALL команде, в стек и загружает ь EIP новое значение, осуществляя тем

Непривилегированные  команды !

самым передачу управления. Если операнд CALL - регистр или переменная, то его значение рассматривается как абсолютное смещение, если операнд - ближ­няя метка в программе, то ассемблер указывает ее относительное смещение. Что­бы выполнить дальний CALL в реальном режиме, режиме V86 или в защищен­ном режиме при переходе в сегмент с теми же привилегиями, процессор помещает в стек значения регистров CS и EIP (IP при 16-битной адресации) и осуществляет дальний переход аналогично команде JMP.

Команда

Назначение

Процессор

RET число

Возврат из процедуры

8086

число

 

 

число

 

 

считывает из стека слово (или двойное слово, в зависимости от режима

адресации) и загружает его в IP (или EIP), выполняя тем самым действия, обрат­ные ближнему вызову процедуры командой CALL. Команда RETF загружает из стека IP (EIP) и CS, возвращаясь из дальней процедуры. Если в программе указа­на команда RET, ассемблер заменит ее на RETN или RETF в зависимости от того, как была описана процедура, которую эта команда завершает. Операнд для RET необязателен, но, если он присутствует, после считывания адреса возврата из сте­ка будет удалено указанное количество байтов - это нужно, если при вызове про­цедуры ей передавались параметры через стек.

Команда

Назначение

Процессор

INT число

Вызов прерывания

8086

INT аналогично команде CALL помещает в стек содержимое регистров EFLAGS, CS и EIP, после чего передает управление программе, называемой обработчиком прерываний с указанным в качестве операнда номером (число от 0 до В ре-

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

по адресу 0000h:0040h. В защищенном режиме адреса обработчиков прерываний

находятся в таблице IDT и обычно недоступны для прямого чтения или

так что для установки собственного обработчика программа должна обращаться к операционной системе. В DOS вызовы прерываний используются для выполне­ния большинства системных функций - работы с файлами, вводом/выводом

и т. д. Например, следующий фрагмент кода завершает выполнение программы

и возвращает управление DOS: mov ax,4C01h

int 21h

Команда Назначение Процессор

IRET IRETD

Возврат из обработчика прерывания 8086

Возврат управления из обработчика прерывания или исключения. IRET за­гружает из стека значения IP, CS и FLAGS, a IRETD - EIP, CS и EFIAGS соот­ветственно. Единственное отличие IRET от RETF состоит в том, что значение ре­гистра флагов восстанавливается, из-за чего многим обработчикам прерываний приходится изменять величину EFLAGS, находящегося в стеке, чтобы, например, вернуть флаг CF, установленный в случае ошибки.

Команда

Назначение

Процессор

INT3

Вызов прерывания 3

8086

Размер этой команды - один байт (код ОССЬ), что делает ее удобной для до­водки программ отладчиками, работающими в реальном режиме. Они записыва­ют этот байт вместо первого байта команды, перед которой требуется точка оста­нова, и переопределяют адрес обработчика прерывания 3 на соответствующую процедуру внутри отладчика.

Команда Назначение . Процессор

INTO Вызов прерывания 4 при переполнении 8086

INTO - еще одна специальная форма команды INT. Она вызывает обработчик прерывания 4, если флаг OF установлен в 1.

Команда Назначение Процессор

BOUND индекс.границы Проверка выхода за границы массива 80186

BOUND проверяет, не выходит ли значение первого операнда (регистр), взя­тое как число со знаком, за границы, указанные во втором операнде (переменная). Границы - два слова или двойных слова (в Зависимости от разрядности операн­дов), рассматриваемые как целые со знаком и расположенные в памяти подряд. Первая граница считается нижней, вторая - верхней. Если индекс меньше ниж­ней границы или больше верхней, вызывается прерывание 5 (или исключение #BR), причем адрес возврата указывает не на следующую команду, а на BOUND, так что обработчик должен исправить значение индекса или границ, прежде чем выполнять команду IRET.

Команда

Назначение

Процессор

ENTER

Вход в процедуру

80186

Команда ENTER создает стековый кадр заданного размера и уровня вложен­ности (оба операнда - числа; уровень вложенности может принимать значения только от 0 до 31) с целью вызова процедуры, использующей динамическое рас­пределение памяти в стеке для своих локальных переменных. Так, команда

enter 2048,3

помещает в стек указатели на стековый кадр текущей процедуры и той, из кото­рой вызывалась текущая, создает стековый кадр размером 2 Кб для вызывг ~мойпроцедуры и помещает в EВP адрес начала кадра. Пусть процедура MAIN имеет уровень вложенности 0, процедура PROCA запускает­ся из MAIN и имеет уровень вложенности 1, и PROCB запускается из PROCA с уровнем вложенности 2. Тогда стек при входе в проце­дуру МАШ имеет вид, показанный на рис. 10.

Теперь процедура МАШ может определять свои локальные переменные в памяти, исполь­зуя текущее значение EВP.

На первом уровне вложенности процедура PROCA, как показано на рис.     может созда-

старый EВP

EВP для MAIN

локальные переменные

для MAIN

EВP

ESP

Рис. 10. Стековый кадр процедуры нулевого уровня (MAIN)

вать свои локальные переменные, применяя текущее значение ЕВР, и получит до­ступ к локальным переменным процедуры МАШ, используя значение ЕВР для МАШ, помещенное в стек командой ENTER.

Процедура PROCB на втором уровне вложен­ности (см. рис. 12) получает доступ как к локаль­ным переменным процедуры PROCA, применяя значение ЕВР для PROCA, так и к локальным переменным процедуры МАШ, используя зна­чение ЕВР для МАШ.

старый ЕВР

ЕВР для MATN

старый EВP

MAIN

локальные переменные

MAIN

локальные переменные для MAIN

ЕВР для MAIN

ЕВР для MAIN

евр для proca

EВP для MAIN

MAIN

EВP для PROCA

локальные

EВP

переменные

для PROCA

локальные переменные для PROCA

ЕВР для PROCA

ЕВР ял* main

ЕВР для PROCA

ЕВР дли PROCB

ESP

локальные переменны* для PROCB

EВP

ESP

Рис. 11. Стековый кадр процедуры первого уровня (PROCA)

Рис. 12. Стековый кадр процедуры

второго уровня (PROCB)

Команда

Назначение

Процессор

LEAVE

Выход из процедуры

80186

Команда выполняет действия, противоположные команде ENTER. Фактически LEAVE только копирует содержимое ЕВР в ESP, тем самым выбрасывая из стека весь кадр, созданный последней выполненной командой ENTER, и считывает из

стека EВP для предыдущей процедуры, что одновременно восстанавливает и зна­чение, которое имел ESP до вызова последней команды ENTER.