Команды LOOPE/LOOPZ и LOOPNE/LOOPNZ




Эти команды похожи на команду LOOP, т. е. заставляют цикл повториться столько раз, сколько указано в регистре СХ, однако они допускают и досрочный выход из цикла.

Цикл по счетчику и пока равно(пока ноль): LOOPE <метка> или LOOPZ <метка>

(Названия LOOPE и LOOPZ являются синонимами.)

Действие этой команды можно описать так:

CX:=CX-1; If (CX<>0) and (ZF=1) then goto <метка>

Таким образом, эта команда совмещает в себе изменение счетчика цикла (регистра СХ) и условный переход, когда счетчик еще не нулевой и когда предыдущая команда выработала флаг нуля, равный 1. Причем этот переход - короткий.

Команда LOOPE используется для организации цикла с известным числом повторений, из которого возможен досрочный выход. До начала цикла в регистр СХ записывается число повторений. Сама команда LOOPE ставится в конец цикла (ее операнд - метка первой команды цикла), а перед ней помещается команда, меняющая флаг ZF (обычно это команда сравнения СМР). Команда LOOPE заставляет цикл повторяться СХ раз, но только если предыдущая команда фиксирует равенство сравниваемых величин (вырабатывает нулевой результат).

По какой именно причине произошел выход из цикла (по ZF=0 или СХ=0), надо проверять после цикла. Причем надо проверять флаг ZF (по команде JE/JZ или JNE/JNZ), а не регистр СХ, т. к. условие ZF=0 ("не равно") может появиться как раз на последнем шаге цикла, когда и регистр СХ стал нулевым.

Чаще всего команда LOOPE используется для поиска первого элемента некоторой последовательности, отличного от заданной величины. Пусть, к примеру, надо записать в регистр BL наименьшее число из отрезка [2, К], на которое не делится число N (К и N - байтовые переменные, 2<=K < N), или записать 0, если такого числа нет. Для этого будем последовательно делить N на числа 2, 3,..., К и сравнивать остатки от деления с 0 - до тех пор, пока не найдется ненулевой остаток либо не будут исчерпаны все числа отрезка:

Еще одна команда ПК для организации циклов:

Цикл по счетчику и пока не равно(пока не ноль):LOOPNE <метка> или LOOPNZ <метка>

(Названия LOOPNE и LOOPNZ являются синонимами.)

Эта команда аналогична команде LOOPE/LOOPZ, но выход из цикла осуществляет при СХ=0 или ZF=1 (если предыдущая команда зафиксировала равенство, дала нулевой результат). Ее действие:

CX:=CX-1; if (CX<>0) and (ZF=0) then goto <метка>

Команда LOOPNE обычно используется для поиска в некоторой последовательности первого элемента, имеющего заданную величину.

Команда LOOP

Пусть некоторую группу команд (тело цикла) надо повторить N раз (N>0). Тогда на ЯА этот цикл можно реализовать по такой схеме:

Как видно, в конце таких циклов всегда применяется одна и та же тройка команд. Учитывая это, в систему команд ПК была введена специальная команда, которая объединяет в себе действия этих трех команд:

Управление циклом по счетчику: LOOP <метка>

Действие этой команды можно описать так:

CX:=CX-1; if CX<>0 then goto <метка>

С помощью команды LOOP наш цикл запишется следующим образом:

Как видно, получилось короче, да и работает команда LOOP быстрее этих трех команд. Поэтому, если можно, следует пользоваться командой LOOP.

Однако необходимо учитывать ряд особенностей этой команды.

Во-первых, команда LOOP требует, чтобы в качестве счетчика цикла обязательно использовался регистр СХ, при другом регистре команду применять нельзя.

Во-вторых, начальное значение для СХ должно быть присвоено до цикла, причем этому регистру надо присваивать ровно столько, сколько раз должен повторяться цикл - без всяких "плюс-минус единица". Например, если цикл должен выполняться 100 раз, то в регистр СХ надо записывать именно 100, а не 99 или 101.

В-третьих, поскольку команда LOOP ставится в конце цикла, тело цикла хотя бы раз обязательно выполнится. Поэтому для случая СХ=0 наша схема цикла не подходит. Так вот, если возможен вариант, что число повторений может быть и нулевым, то при СХ=0 надо сделать обход цикла:

Именно ради осуществления таких обходов в ПК и была введена команда условного перехода JCXZ. В иных ситуациях она используется редко.

В-четвертых, как и команды условного перехода, команда LOOP реализует только короткий переход, поэтому расстояние от нее до начала цикла (метки L) не должно превышать 127-128 байтов (примерно 30-40 команд). Если цикл содержит больше команд, тогда команду LOOP использовать нельзя и надо реализовывать цикл по-иному.

Рассмотрим конкретный пример на использование команды LOOP. Пусть N -байтовая переменная со значением от 0 до 8 и надо в регистр АХ записать факториал этого числа: AX:=N! (отметим, что 8! = 40320 < 216).

Для решения этой задачи надо вначале положить АХ:=1, а затем N раз выполнить умножение AX:=AX*i, меняя i от 1 до 8. При этом следует учитывать, что при N=0 цикл не должен выполняться.

Отметим, что в данном примере параметр цикла (i) можно было бы менять и в "обратном" направлении - от N до 1, а поскольку именно так меняется и регистр СХ, то этот регистр можно использовать не только как счетчик цикла, но и как параметр цикла (CX=i):

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



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-02-16 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: