Организация циклов

Цикл, как известно, представляет собой важную алгоритмическую структуру, без использования которой не обходится, наверное, ни одна программа. Организовать циклическое выполнение некоторого участка программы можно, к примеру, используя команды условной передачи управления или команду безусловного перехода jmp. При такой организации цикла все операции по его организации выполняются “вручную”. Но, учитывая важность такого алгоритмического элемента, как цикл, разработчики микропроцессора ввели в систему команд группу из трех команд, облегчающую программирование циклов. Эти команды также используют регистр ecx/cx как счетчик цикла.

Дадим краткую характеристику этим командам:

§ loop метка_перехода (Loop, управление циклом по cx) — повторить цикл. Команда позволяет организовать циклы, подобные циклам for в языках высокого уровня с автоматическим уменьшением счетчика цикла. Выполнение команды не влияет на флаги. Работа команды заключается в выполнении следующих действий:

· декремента регистра ecx/cx (счетчик цикла);

· сравнения регистра ecx/cx с нулем:

o если (ecx/cx) > 0, то управление передается на метку перехода;

o если (ecx/cx) = 0, то управление передается на следующую после loop команду.

Применение:
Команду loop применяют для организации цикла со счетчиком. Количество повторений цикла задается значением в регистре ecx/cx перед входом в последовательность команд, составляющих тело цикла. Помните о двух важных моментах:

· для предотвращения выполнения цикла при нулевом ecx/cx используйте команду jecxz/jcxz. Если этого не сделать, то при изначально нулевом ecx/cx, инструкция loop вычтет из нуля единицу, и в результате получится число 0ffffffff/0ffff, а это значит, что вместо нуля цикл выполнится 4 294 967 295/65 535 раз;

· смещение метки, являющейся операндом loop, не должно выходить из диапазона -128...+127 байт. Это смещение, как и в командах условного перехода, является относительным от значения счетчика адреса следующей за loop команды.

mov cx,10... jcxz m1; если сх=0, цикл обойтиcycl:;тело цикла loop cyclm1:

§ loope/loopz метка_перехода (Loop till cx <> 0 or Zero Flag = 0, управление циклом по cx c учетом значения флага ZF) — повторить цикл, пока cx <> 0 или zf = 0. Команды loope и loopz — абсолютные синонимы, поэтому используйте ту команду, которая вам больше нравиться. выполнение команды не влияет на флаги. Работа команд заключается в выполнении следующих действий:

· декремента регистра ecx/cx;

· сравнения регистра ecx/cx с нулем;

· анализа состояния флага нуля zf:

o если (ecx/cx) > 0 и zf = 1, управление передается на метку перехода;

o если (ecx/cx) = 0 или zf = 0, управление передается на следующую после loop команду.

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

§ loopne/loopnz метка_перехода (Loop till cx <> 0 or Not Zero flag=0) — повторить цикл пока cx <> 0 или zf = 1. Команды loopne и loopnz также абсолютные синонимы. выполнение команды не влияет на флаги. Работа команд заключается в выполнении следующих действий:

· декремента регистра ecx/cx;

· сравнения регистра ecx/cx с нулем;

· анализа состояния флага нуля zf:

o если (ecx/cx) > 0 и zf = 0, управление передается на метку перехода;

o если (ecx/cx)=0 или zf=1, управление передается на следующую после loop команду.

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

Команды loope/loopz и loopne/loopnz по принципу своей работы являются взаимообратными. Они расширяют действие команды loop тем, что дополнительно анализируют флаг zf, что дает возможность организовать досрочный выход из цикла, используя этот флаг в качестве индикатора.

Недостаток команд организации цикла loop, loope/loopz и loopne/loopnz в том, что они реализуют только короткие переходы (от –128 до +127 байт). Для работы с длинными циклами придется использовать команды условного перехода и команду jmp.

Применение:
Команды loopxx удобно использовать вместе с командами, которыe в результате своей работы меняют значение флага zf. Типичный пример — команда сравнения cmp.

;найти первый пробел в строке символовstr db 'Найти первый пробел'str_size=$-str... cld mov cx,str_size lea si,strcycl: lodsb cmp al,' ' loopne cycl jcxz m1;переход, если пробелов нет dec si;в si — адрес пробела в строке str...m1

Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: