Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Микропроцессорные системы (книга Комаров) / Программирование на Ассемблере (ч 2).doc
Скачиваний:
155
Добавлен:
08.03.2015
Размер:
380.93 Кб
Скачать

Команды перехода по состоянию регистра cx

К этой подгруппе относится единственная команда JCXZ, которая передает управление по указанной метке, если (CX)=0.

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

Пример 3.95:

MOV CX,Count ; Чтение счетчика циклов

JCXZ EndLoop ; Переход, если счетчик=0

. . . . . . . . . ; Тело цикла

. . . . . . . . .

EndLoop: . . . . . . . . . ; Продолжение программы

; при (Count)=0

Очень часто в программах необходимо совершать условные переходы за пределы короткого диапазона (полные внутрисегментные переходы, межсегментные переходы). Такие условные переходы реализуются командами JMP, выполняемыми при истинности противоположного условия.

Пример 3.96:

Выполнить межсегментный условный переход на метку Zero при флаге нуля ZF=1:

JNZ Cont ; Анализ противоположного условия ZF=0

JMP FAR PTR Zero ; Межсегментный переход при ZF=1

Cont:. . . . . . . . . . . . ; Продолжение программы при ZF=0

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

Команды управления циклами используются для условной передачи управления при организации циклов. Они записываются в формате:

LOOPcond Labl,

где cond  дополнительное формальное условие перехода.

При этом основным проверяемым условием для всех команд является содержимое счетчика циклов, в качестве которого служит регистр CX. Каждая команда управления циклами прежде всего декрементирует регистр CX, а затем анализирует его. Если (CX)< >0, то управление передается на начало цикла по указанной метке Labl. Если (CX)=0, то выполняется очередная команда программы.

Все переходы, реализуемые командами управления циклами, являются короткими. Это также обусловлено тем, что их машинный код содержит лишь один байт для хранения дистанции disp8, который используется при вычислении адреса перехода (IP)=(IP)+disp8(Labl).

Дополнительное условие перехода cond либо отсутствует в команде, либо сводится к анализу флага ZF и принимает значения Z/E или NZ/NE.

Основной командой этой подгруппы является команда LOOP, в которой дополнительное условие перехода отсутствует. Она записывается в формате:

LOOP Labl.

Команда LOOP повторяет цикл, пока (CX)< >0 и завершает его при (CX)=0. Она используется для организации циклов с постусловием. При этом фрагмент программы имеет вид:

MOV CX, Count ; Загрузка счетчика циклов

Begin:. . . . . . . . . ; Тело цикла

. . . . . . . . .

LOOP Begin ; Зацикливание, если (CX)< >0

. . . . . . . . . ; Продолжение программы

Пример 3.97:

Выполнить зеркальную перестановку битов в регистре AL (см. пример 3.90).

MOV CX, 8 ; Загрузка счетчика циклов

Next: RCL AL, 1 ; Выделение бита

RCR DL, 1 ; Формирование результата

LOOP Next

MOV AL, DL ; Пересылка результата

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

Для организации таких циклов предназначены команды LOOPZ/LOOPE и LOOPNZ/LOOPNE. Как правило, они используются после команды сравнения CMP.

Команда LOOPZ/LOOPE повторяет цикл до тех пор, пока (CX)< >0 и ZF=1. Следовательно, цикл завершается, если либо (CX)=0, либо ZF=0. Обычно эта команда применяется для организации циклов с целью поиска первого несовпадающего элемента в некотором массиве.

Команда LOOPNZ/LOOPNE повторяет цикл до тех пор, пока (CX)< >0 и ZF=0. Следовательно, цикл завершается, если либо (CX)=0, либо ZF=1. Обычно эта команда применяется для организации циклов с целью поиска первого совпадающего элемента в некотором массиве.

Таким образом, команды LOOPZ/LOOPE и LOOPNZ/LOOPNE допускают два варианта завершения цикла. Вариант завершения легко определить путем анализа состояния флага ZF после выхода из цикла. Например, если после завершения цикла командой LOOPNZ/LOOPNE оказывается, что ZF=1, то цикл завершен по совпадению элементов, а при ZF=0  по счетчику цикла, так как совпадений не было.

Пример 3.98:

Найти первый нулевой элемент в массиве байтов Array:

LEA BX, Array1 ; Загрузка адреса и

MOV CX, LENGTH Array ; счетчика циклов

Next: INC BX ; Модификация адреса

CMP BYTE PTR [BX], 0 ; Сравнение с нулем

LOOPNZ Next

JNZ NotFound ; Переход, если нуль не найден

. . . . . . . . . . . . ; Продолжение при наличии

. . . . . . . . . . . . ; нулевого элемента

NotFound: . . . . . . . . . . . . ; Продолжение при отсутствии

. . . . . . . . . . . . ; нулевого элемента

В данном примере команда модификации адреса INC расположена перед командой CMP, что вызывает его инкрементирование перед первым сравнением. Поэтому для получения достоверного адреса первого элемента начальный адрес массива Array загружен в регистр BX на единицу меньшим значением. Команда INC не может находиться за командой CMP, так как она изменяет флаг ZF, искажая результат сравнения, полученный CMP и требующийся для LOOPNZ.