Обратимся теперь к командам условного перехода. В их мнемонические обозначения входят буквы, которые определяют условия в соответствии с нижеприведенной таблицей:
Буква мнемокода
Условие
Тип операндов
Е
равно
любые
N
Не равно
любые
G
больше
Числа со знаком
L
меньше
Числа со знаком
А
Выше, в смысле “больше”
Числа без знака
В
ниже, в смысле “меньше”
Числа без знака
Операнд “метка перехода” или “близкая метка” отражает тот факт, что метка помеченной команды должна находиться в пределах текущего сегмента кода и на относительном расстоянии от команды перехода >-128 и < 127 байтов. Ограничение –128:127 байтов снято у процессоров, начиная с модели 80386, однако ограничение передачи управления в пределах текущего сегментного кода действует и в моделях Пентиум.
Решение о том, куда будет передано управление командой условного перехода, принимается на основании условия. Источниками таких условий могут быть:
- любая команда, изменяющая состояние арифметических флагов (ниже эти флаги будут перечислены);
- команда сравнения CMP.
В последних публикациях по программированию на Ассемблере среди команд передачи управления рассматривают команду сравнения CMP, хотя эта команда ближе к арифметическим операциям. Объясняется это тем, что, как правило, команды безусловного перехода в программах следуют за командой сравнения, ибо именно сравнение лежит в основе решения (символа процесса).
Формат команды CMP:
CMP приемник, источник или
CMP операнд1, операнд2
Эта команда осуществляет по сути вычитание операнд_1 - операнд_2 или приемник – источник, однако результат никуда не записывает, а только устанавливает флаги в соответствие с нижеприведенной таблицей.
Сравниваемые операнды
Флаги
OF
SF
ZF
CF
Операнды без знака
Источник < приемник
Н
Н
Источник = приемник
Н
Н
Источник > приемник
Н
Н
Операнды со знаком
Источник < приемник
0/1
H
Источник = приемник
H
Источник > приемник
0/1
H
В этой таблице приняты следующие обозначения:
- “H” означает, что ‘не имеет значения” или иначе, на этот флаг операция не влияет;
- 0/1 означает, что флаг устанавливается или в 1 или в 0 в зависимости от значений операндов (отрицательные или положительные или разнознаковые операнды сравниваются).
Приведем еще одну таблицу, в которой отражается действие команд условного перехода по значениям анализируемых этими командами флагов:
Тип операндов
Мнемокод команды
Критерий перехода
Значения флагов для перехода
любые
JE
Операнд_1=операнд_2
ZF=1
Любые
JNE
Операнд_1<>операнд_2
ZF=0
Со знаком
JL/JNGE
Операнд_1<операнд_2
SF<>OF
Со знаком
JLE/JNG
Операнд_1<=операнд_2
SF<>OF или ZF=1
Со знаком
JG/JNLE
Операнд_1>операнд_2
SF=OF и ZF=0
Со знаком
JGE/JNL
Операнд_1>=операнд_2
SF=OF
Без знака
JB/JNAE
Операнд_1<операнд_2
CF=1
Без знака
JBE/JNA
Операнд_1<=операнд_2
CF=1 или ZF=1
Без знака
JA/JNBE
Операнд_1>операнд_2
CF=0 и ZF=0
Без знака
JAE/JNB
Операнд_1=>операнд_2
CF=0
В приведенной таблице по сути присутствуют 3 группы команд условного перехода, которые названы “любые”, “без знака” и “со знаком”. Беззнаковое число подразумевает, что все его биты – биты данных. Типичные примеры таких чисел – порядковые номера элементов в списке, коды символов, телефонные номера и т.п. Знаковые числа подразумевают, что старший разряд (первый слева) соответствует знаку (значение бита 0 соответствует знаку ‘+’, а значение 1 – знаку ‘-‘.Предположим, CL содержит 11000110, а DL –00101100. Команда CMP CL,DL сравнивает содержимое регистров. Если интерпретировать содержимое регистров как беззнаковые числа, то значение в CL больше, а если в регистрах числа со знаком, то DL больше, поскольку как число со знаком значение в CL является отрицательным.
Приведу примеры использования команд условного перехода.
Положим, значения длин сторон треугольника обозначены a, b и c и занесены в байтовые переменные с такими же именами. Положим, что в программе осуществляется проверка значений сторон треугольника на предмет его идентификации: является ли треугольник со сторонами a, b и c равносторонним, равнобедренным или общего типа. Заметим, что стороны треугольника всегда принимают положительные значения, поэтому в программе нужно применять условные команды группы “без знака. Приведу фрагмент схемы программы и соответствующие команды на языке ассемблера. Узлом и меткой К обозначены команды завершения программы. Поскольку пока мы не изучили команд прерывания для выдачи сообщений на экран дисплея, в приведенном фрагменте программы такие команды отсутствуют, но отмечены места, где они должны быть вставлены.
MOV AL,A
MOV BL,B
MOV СL,С
CMP AL,BL
A=b и b=c?
JNE NOT_EQABC
ДА CMP BL,CL
JNE NOT_EQABC
. . . . . . . . . . . . . . . .
здесь поместить команды
выдачи сообщения
НЕТ “треугольник равносторонний”
Выдача сообщения “треугольник равносторонний”
JMP K ; переход
; на метку K
NOT_EQABC: CMP AL,BL
JE EQUAL
a=b или b=c или a=c?
CMP BL,CL
JE EQUAL
НЕТ CMP AL,CL
К
JE EQUAL
Выдача сообщения “треугольник обычный”
. . . . . . . . . . . . . .
да здесь поместить команды
выдачи сообщения
Выдача сообщения “треугольник равнобедренный”
ДА “треугольник обычный ”
JMP K ; переход к К
EQUAL:
. . . . . . . . . . . . . . . . . . .. .
К
здесь поместить команды
выдачи сообщения
“треугольник равнобедренный”
К: RET
К
Рисунок 1. Фрагмент программы идентификации треугольника
Обратите внимание! Команды сравнения и условного перехода, набранные в приведенном выше фрагменте программы курсивом, реализуют функцию логического И, а команды, набранные обычным шрифтом, реализуют функцию логического ИЛИ.
В следующей таблице приводятся специальные инструкции условного перехода.
мнемокод
Описание
Проверяемые флаги
JCXZ
Перейти, если CX=0
нет
JC
Перейти при переносе (аналогично JB)
CF=1
JNC
Перейти при отсутствии переноса
CF=0
JO
Перейти при переполнении
OF=1
JNO
Перейти при отсутствии переполнения
OF=0
JP/JPE
Перейти при четности
PF=1
JNP/JPO
Перейти при нечетности
PF=0
JS
Перейти при наличии отрицательного знака
SF=1
JNS
Перейти при отсутствии отрицательного знака
SF=0
Примером применения логических команд и команд условного перехода может быть следующий фрагмент программы:
OR DX,DX ;проверить значение в регистре
JZ M1 ;если DX=0, перейти на метку М1
JS M2 ;если DX<0, перейти на меткуМ2
TEST DX,00000001B ;проверить младший бит
JZ CHET ;если бит нулевой, число в DX четное
NECHET: . . . . . .;если бит ненулевой, число в DX нечетное
. . . . . Здесь предусмотреть обработку нечетного значения.
Следует отметить, что в этом фрагменте на чет-нечет будут проверяться не все возможные значения, а только значения из определенного диапазона. Подумайте и ответьте: какой это диапазон?