Эти команды реализуют изменение естественного порядка выполнения команд программы. Их можно разделить на 3 подгруппы, описание которых сведено в таблицу 4.
Мнемокод | Формат |
Команды безусловной передачи управления CALL | CALL имя |
RET | RET [число удаляемых из стека значений] |
JMP | JMP имя |
Команды условной передачи управления | |
JA / JNBE | JA / JNBE близкая метка |
JAE / JNB | JAE / JNB близкая метка |
JNC | JNC близкая метка |
JB / JNAE | JB / JNAE близкая метка |
JC | JC близкая метка |
JBE / JNA | JBE / JNA близкая метка |
JCXZ | JCXZ близкая метка |
JE / JZ | JE / JZ близкая метка |
JG / JNLE | JG / JNLE близкая метка |
JGE / JNL | JGE / JNL близкая метка |
JL / JGNE | JL / JGNE близкая метка |
JLE / JNG | JLE / JNG близкая метка |
JNE / JNZ | JNE / JNZ близкая метка |
JNO | JNO близкая метка |
JNP / JPO | JNP / JPO близкая метка |
JNS | JNS близкая метка |
JO | JO близкая метка |
JP / JPE | JP / JPE близкая метка |
JS | JS близкая метка |
Команды управления циклами LOOP | LOOP близкая метка |
LOOPE / LOOPZ | LOOPE / LOOPZ близкая метка |
LOOPNE / LOOPNZ | LOOPNE / LOOPNZ близкая метка |
В приведенной таблице через слеш ‘/’ перечисляются идентичные команды, действие которых совершенно одинаково и применение конкретной из них зависит от пристрастий программиста. Наличие идентичных команд объясняется тем фактом, что если число_1 >число_2, то можно с уверенностью утверждать, что число_1 не (меньше или равно) число_2.
Обратимся теперь к командам условного перехода. В их мнемонические обозначения входят буквы, которые определяют условия в соответствии с нижеприведенной таблицей:
Буква мнемокода | Условие | Тип операндов |
Е | равно | любые |
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
JNE NOT_EQABC
ДА CMP BL,CL
JNE NOT_EQABC
. ...............
здесь поместить команды
выдачи сообщения
НЕТ “треугольник равносторонний”
|
; на метку K
NOT_EQABC: CMP AL,BL
JE EQUAL
CMP BL,CL
JE EQUAL
НЕТ CMP AL,CL
JE EQUAL
|
здесь поместить команды
выдачи сообщения
ДА “треугольник обычный ”
JMP K; переход к К
|
. ....................
здесь поместить команды
выдачи сообщения
“треугольник равнобедренный”
К:
RET
Рисунок Фрагмент программы идентификации треугольника
Обратите внимание! Команды сравнения и условного перехода, набранные в приведенном выше фрагменте программы курсивом, реализуют функцию логического И, а команды, набранные обычным шрифтом, реализуют функцию логического ИЛИ.
В следующей таблице приводятся специальные инструкции условного перехода.
мнемокод | Описание | Проверяемые флаги |
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 нечетное
..... Здесь предусмотреть обработку нечетного значения.
Следует отметить, что в этом фрагменте на чет-нечет будут проверяться не все возможные значения, а только значения из определенного диапазона. Подумайте и ответьте: какой это диапазон?