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


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

Инструкция условного перехода может осуществлять или нет переход на целевую (указанную в ней) метку, в зависимости от сос-тояния регистра флагов. Рассмотрим следующий пример:

mov ah,1 ; функция DOS ввода с клавиату-

; ры

int 21h ; получить следующую нажатую

; клавишу

cmp al,’A’ ; была нажата буква «A»?

je AWasTyped ; да, обработать ее

mov [TampByte], al ; нет, сохранить символ

.

.

.

AWasTyped:

push ax ; сохранить символ в стеке

.

.

.

Сначала в данной программе с помощью функции операционной системы DOS воспринимается нажатая клавиша. Затем для сравнения введенного символа с символом A используется инструкция CMP. Эта инструкция аналогична инструкции SUB, только ее выполнение ни на что не влияет, поскольку назначение данной инструкции состоит в том, чтобы можно было сравнить два операнда, установив флаги так же, как это делается в инструкции SUB. Поэтому в предыдущем при-мере флаг нуля устанавливается в значение 1 только в том случае, если регистр AL содержит символ A.

Теперь мы подошли к основному моменту. Инструкция JE предс-тавляет инструкцию условного перехода, которая. осуществляет пе-редачу управления только в том случае, если флаг нуля равен 1. В противном случае выполняется инструкция, непосредственно следую-щая за инструкцией JE (в данном случае — инструкция MOV). Флаг нуля в данном примере будет установлен только в случае нажатия клавиши A, и только в этом случае процессор 8086 перейдет к вы-полнению инструкции с меткой AWasTyped, то есть инструкции PUSH.

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

Перечень инструкций условных переходов приводится в Таблице 5.2.

Инструкции условных переходов Таблица 5.2

Название Значение Проверяемые флаги

JB/JNAE Перейти, если меньше / перейти, если CF = 1

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

JAE/JNB Перейти, если больше или равно / пе- CF = 0

рейти, если не меньше

JBE/JNA Перейти, если меньше или равно / пе- CF = 1 или ZF = 1

рейти, если не больше

JA/JNBE Перейти, если больше / перейти, если CF = 0 и ZF = 0

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

JE/JZ Перейти, если равно ZF = 1

JNE/JNZ Перейти, если не равно ZF = 0

JL/JNGE Перейти, если меньше чем / перейти, SF = OF

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

JGE/JNL Перейти, если больше чем или равно / SF = OF

перейти, если не меньше чем

JLE/JNLE Перейти, если меньше чем или равно / ZF = 1 или SF = OF

перейти, если не больше, чем

JG/JNLE Перейти, если больше чем / перейти, ZF = 0 или SF = OF

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

JP/JPE Перейти по четности PF = 1

JNP/JPO Перейти по нечетности PF = 0

JS Перейти по знаку SF = 1

JNS Перейти, если знак не установлен SF = 0

JC Перейти при наличии переноса CF = 1

JNC Перейти при отсутствии переноса CF = 0

JO Перейти по переполнению OF = 1

JNO Перейти при отсутствии переполнения OF = 0

CF — флаг переноса, SF — флаг знака, OF — флаг переполне-

ния, ZF — флаг нуля, PF — флаг четности

Более подробная информация об инструкциях-синонимах и общие сведения об инструкциях перехода содержатся в Главе 6. Там также подробно рассказывается о способах, с помощью которых инструкции процессора 8086 могут изменять регистр флагов.

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

.

.

.

JumpTarget:

.

.

.

DB 1000 DUP (?)

.

.

.

dec ax

jnz JumpTarget

.

.

.

так как метка JumpTarget отстоит от инструкции JNZ более чем на 1000 байт. В данном случае нужно сделать следующее:

.

.

.

JumpTarget:

.

.

.

DB 1000 DUP (?)

.

.

.

dec ax

jnz SkipJump

jmp JumpTarget

SkipJump:

.

.

.

где условный переход переход применяется для того, чтобы опреде-лить, нужно ли выполнить длинный безусловные переход.

Загрузка...