Циклы способы организации циклов

Циклы способы организации циклов

Лекция
доцента кафедры ИВТ Гродненского госуниверситета
канд. техн. наук Ливак Елены Николаевны

    В лекции:
    Организация цикла с помощью команд условного перехода и регистра ecx/cx.
    Организация цикла с помощью команды безусловного перехода jmp и регистра ecx/cx.
    Организация цикла с помощью специальных команд.

      Организация цикла с помощью команды loop.
      Организация цикла с помощью команд loope/loopz.
      Организация цикла с помощью команд loopne/loopnz.

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

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

Рассмотрим особенности способов организации циклов.

Первый способ — организация цикла с помощью команд условного перехода и регистра ecx/cx .

Напомним, что в архитектуре микропроцессоров Intel регистр ecx/cx имеет определенное функциональное назначение — выполняет роль счетчика.

Если некоторую группу команд необходимо повторить определенное количество раз, цикл можно организовать следующим образом: 1) поместить в регистр ecx/cx количество повторений; 2) первую команду тела цикла отметить меткой; 3) после выполнения тела цикла уменьшить содержимое регистра ecx/cx на 1; 4) выполнить сравнение содержимого регистра ecx/cx с нулем; 5) в случае, если ecx/cx ≠ 0, осуществить переход на метку, иначе выполнять следующую за телом цикла команду.

Схема реализации будет выглядеть таким образом:

Внимание. Необходимо обращать внимание на выполнение «пустого» цикла.Если вдруг начальное значение в регистре cx равно нулю, то после уменьшения на единицу, содержимым регистра станет число FFFFh (-1 в десятичной системе счисления). В результате цикл повторится еще 65535 раз (или 4 294 967 295 раз при использовании регистра ecx ). Поэтому следует всегда проверять содержимое регистра ecx/cx для предотвращения выполнения «пустого» цикла. Такую проверку легко организовать с помощью команды условного перехода jcxz/jecxz . Синтаксис команды: jcxz Либо в случае необходимости использования расширенного регистра jecxz

Перевод-расшифровка аббревиатуры названия команды — Jump if cx is Zero — переход, если cx равно нулю. Замечание. Команда jcxz/jecxz может адресовать только короткие переходы (на –128 или на +127 байт от следующей за ней команды).

Итак, схема организации цикла с предотвращением выполнения «пустого» цикла Второй способ — организация цикла с помощью команды безусловного перехода jmp и регистра ecx/cx . Цикл можно организовать и следующим образом: 1) поместить в регистр ecx/cx количество повторений; 2) осуществить проверку на «пустой» цикл командой jecxz/jcxz 3) эту команду проверки отметить меткой начала цикла; 4) после выполнения тела цикла уменьшить содержимое регистра ecx/cx на 1; 5) выполнить безусловный переход на начало цикла.

Схема реализации будет выглядеть таким образом:

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

Третий способ — организация цикла с помощью специальных команд .

Заметим, что в описанных первых двух способах организации цикла большинство операций выполняются “вручную” (декремент регистра cx, сравнение cx с нулем, переход на начало цикла).

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

    Это команды

      loop
      loope/loopz
      loopne/loopnz

    Обратим внимание, эти команды также используют регистр ecx/cx как параметр (счетчик) цикла.

Организация цикла с помощью команды loop

В переводе Loop означает «петля», или другими словами «повторить цикл».
Синтаксис команды: loop

Работа команды заключается в выполнении следующих действий:

1) уменьшение значения регистра ecx/cx на 1;

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

если ecx/cx = 0, то осуществляется выход из цикла, т.е. управление передается на следующую после loop команду; иначе — управление передается на метку перехода (цикл повторяется).

Порядок организации цикла с помощью команды loop :

1) в регистр cx поместить значение, равное количеству повторений; 2) установить метку на первую команду тела цикла; 3) выполнить команду loop .

Схема реализации выглядит следующим образом:

Обратим внимание также на то, что после выхода из цикла содержимое регистра cx всегда равно нулю.

Пример 1.
Необходимо подсчитать сумму элементов массива

Организация цикла с помощью команд loope / loopz.

Заметим, что команды loope и loopz — абсолютные синонимы. Использовать можно любую из них.
Синтаксис команд:

При использовании этих команд цикл повторяется до тех пор, пока cx ≠ 0 и zf = 1 . Выход из цикла осуществляется при выполнении одного из двух условий:
cx = 0 или zf = 0 .

Работа команд заключается в выполнении следующих действий: 1) уменьшение значения регистра ecx/cx на 1; 2) сравнение регистра ecx/cx с нулем: если ( ecx/cx ) = 0, осуществляется выход из цикла; 3) анализ состояния флага нуля zf : если zf = 0 , осуществляется выход из цикла. Таким образом, цикл повторяется, если cx ≠ 0 и zf = 1 .

Напомним, что флаг нуля zf принимает значение 0, когда сравниваемые операнды не равны между собой, и значение 1, если операнды совпадают. Для наглядности изобразим это схематически:

Поэтому, используя этот флаг в качестве индикатора удобно организовать досрочный (до того, как значение cx станет 0) выход из цикла.

Порядок организации цикла с помощью команды loope : 1) в регистр cx поместить значение, равное количеству повторений; 2) установить метку на первую команду тела цикла; 3) использовать команду cmp для сравнения операндов (здесь будет установлен флаг нуля); 4) выполнить команду loope .

Схема реализации выглядит следующим образом:

Совет. Так как флаг нуля принимает значение 0 в случае несовпадения операндов и, соответственно, выход из цикла осуществляется именно при несовпадении операндов, команды loope/loopz удобно использовать для поиска первого элемента последовательности, отличного от заданной величины.

Пример 2.
Необходимо проверить, совпадают ли два массива.

Очевидно, что повторяющимся фрагментом программы будет участок кода, выполняющий сравнение соответствующих элементов массивов. Обратим внимание на то, что досрочный выход из цикла необходимо будет осуществить, как только будет найдена первая несовпадающая пара. Остальные элементы массивов сравнивать далее нет смысла. Поэтому при реализации данной задачи для организации цикла удобно использовать команду loope/loopz.

Реализуем фрагмент программы, осуществляющей проверку десятиэлементных массивов, элементы которых — двухбайтовые числа. Результат в виде признака 0 или 1 запишем в поле rez. Пусть признаком совпадения будет значение 1, признаком несовпадения —0.

Задание. Рассмотрите самостоятельно вопрос о необходимости размера поля Rez, равного 2 байтам, а также целесообразности записи признака предварительно в регистр dx . Внесите соответствующие изменения в текст программы, допишите необходимые команды и выполните программу.

Организация цикла с помощью команд loopne/loopnz.

Заметим, что команды loopne/loopnz являются обратными командам loope/loopz .
Loopne и loopnz также абсолютные синонимы, использовать можно любую из них.

При использовании этих команд цикл повторяется до тех пор, пока
cx ≠ 0 и zf = 0.
Выход из цикла осуществляется при выполнении одного из двух условий:
cx = 0 или zf = 1.

Работа команд заключается в выполнении следующих действий:

1) уменьшение значения регистра ecx/cx на 1;

2) сравнение регистра ecx/cx с нулем: если ( ecx/cx ) = 0, осуществляется выход из цикла;

3) анализ состояния флага нуля zf : если zf = 1, осуществляется выход из цикла.

Таким образом, цикл повторяется, если cx ≠ 0 и zf = 0.

Порядок организации цикла с помощью команды loopne :
1) в регистр cx поместить значение, равное количеству повторений;
2) установить метку на первую команду тела цикла;
3) использовать команду cmp для сравнения операндов (здесь будет установлен флаг нуля);
4) выполнить команду Loopne .

Схема реализации выглядит следующим образом:

Совет. Так как флаг нуля принимает значение 1 в случае совпадения операндов и, соответственно, выход из цикла осуществляется именно при совпадении операндов, команды loopne/loopnz удобно использовать для поиска первого элемента последовательности, имеющего заданную величину.

Пример 3.
Необходимо проверить, есть ли в массиве нулевые элементы, и вывести соответствующее сообщение.

Очевидно, что повторяющимся фрагментом программы будет участок кода, выполняющий сравнение очередного элемента массива с заданным значением — ноль. Обратим внимание на то, что досрочный выход из цикла необходимо будет осуществить, как только будет найден первый элемент равный нулю, так как в данном случае значение остальных элементов массива нас интересовать уже не будут. Поэтому при реализации данной задачи для организации цикла следует использовать команду loopne/loopnz.

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

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

Напомним, что только команда безусловного перехода jmp позволяет осуществлять длинные переходы, так как в коде команды под смещение адреса перехода отводится два байта.

Для организации длинных циклов следует использовать команды условного перехода и команду jmp.

Схема реализации длинного цикла:

То есть, для организации длинного цикла необходимо «вручную» уменьшать содержимое параметра (счетчика) цикла и сравнивать полученное значение с нулем. Когда выполнено определенное количество повторений (cx = 0) , с помощью команды условного перехода je следует выйти из цикла, иначе — командой безусловного перехода jmp необходимо осуществить переход на начало цикла.

Источник

Типы циклов в языках программирования: for, foreach, while и do while

Авторизуйтесь

Типы циклов в языках программирования: for, foreach, while и do while

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

Типы циклов

Цикл For

i — это переменная-счётчик, которая сначала равна нулю. До тех пор, пока она меньше 10, выполняется тело цикла, затем счетчик увеличивается на единицу. For — цикл с предусловием. Это значит, что сначала проверяется условие, и если оно true, то тело выполняется. В скобках объявляется тип переменной счётчика и её начальное значение. Затем указывается условие конца цикла и способ, которым изменяется значение счётчика.

Цикл Foreach (или совместный цикл)

Тело этого цикла выполнится для каждого элемента коллекции. В переменной element будет доступен по очереди каждый элемент массива array.

Цикл While

Относится к тому же типу циклов, что и For, — цикл с предусловием. С его помощью можно создать безусловный цикл, например while(1) — бесконечный цикл. Чтобы его закончить, нужно использовать служебное слово break.

Цикл Do While

Do While относится к типу циклов с постусловием. Однако здесь код выполнится как минимум один раз, даже если условие false.

Вложенные циклы

Циклы можно помещать внутрь друг друга. Это удобно для перебора многомерных коллекций. Код в примере выше выведет в консоль значение каждого элемента из двумерного массива array.

Операторы циклов

Break

Оператор break используется для досрочного выхода из цикла. Когда программа встречает break, цикл немедленно завершается и начинает выполняться код, следующий за циклом.

Continue

Оператор Continue даёт циклу команду выйти из текущей итерации и перейти к следующей.

Этот код выведет в консоль все нечетные числа из диапазона от 0 до 10:

Источник

Циклы способы организации циклов

Очень часто возникает необходимость выполнить один и тот же оператор (или группу операторов) несколько раз. Для этого в языке Pascal предусмотрены операторы циклов.

1. Оператор цикла с предусловием.

Форма записи: while do ;

Здесь while (пока), do <делать) — зарезервированные слова.

В качестве оператора может быть любой простой или составной оператор. Здесь выполняется только в том случае и до тех пор, пока истинно , которое проверяется каждый раз после выполнения оператора. Если с самого начала условие имеет значение false , оператор цикла не выполнится ни разу.

Блок-схема алгоритма работы такого оператора приведена на рис. 1.

Рис. 1. Оператор цикла с предусловием

Пример

. Вычисление факториала числа п (т.е. произведения 1 • 2 • . • п ):

Var i, fact:integer;

WriteLn(‘факториал’, n, ‘ = ‘,Fact:10)

2. Оператор цикла с постусловием. Блок-схема алгоритма работы Оператора приведена на рис.2.

Рис. 2. Оператор цикла с постусловием

Здесь Repeat <повторять до тех пор), Until (пока не будет выполнено условие) — зарезервированные слова.

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

Пример:

. Вычисление факториала числа п (т.е. произведения 1 • 2 • . • п ):

Var i, fact:integer;

WriteLn(‘ Факториал ‘, n, ‘ = ‘,Fact:10)

Здесь I – это счетчик повторов, который необходимо изменять вручную в цикле.

3. Оператор цикла с параметром.

Этот цикл позволяет повторять действия заведомо известное количество раз.

FOR счетчик= нач_значение TO конечное_значение DO

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

Пример:

Вычисление факториала числа п (т.е. произведения 1 • 2 • . • п ):

Var i, fact:integer;

WriteLn (‘ Факториал ‘, n, ‘ = ‘,Fact:10)

В качестве оператора можно использовать любой простой или со ставной оператор.

При использовании этого оператора цикла нужно помнить следующие правила:

1) в качестве параметра можно использовать простую переменную, описанную в этом же блоке;

2) параметр должен иметь дискретный тип;

3) начальное и конечное значения должны иметь тот же тип, что и параметр;

4)в теле цикла (операторе) явное изменение значения параметра (например, оператором присваивания) может привести к бесконечному циклу;

5) нельзя в теле цикла изменить начальное и конечное значения па раметра, если они заданы переменными;

6) после завершения работы цикла значение параметра становится равным конечному значению параметра, если цикл не был прерван оператором перехода.

САМОСТОЯТЕЛЬНО

1. Напишите программу, которая выводит на экран в зонном формате числа:

2. Решить задачу тремя способами (с помощью разных видов цикла):

Через сколько лет L величина вклада достигнет желаемой суммы S (руб.), при начальном вкладе V (руб.), если ежегодный процент, гарантированный банком, составляет 10% от величины вклада.

Исполнить алгоритм при S = 100000 руб., V = 10000 руб.

Источник

Читайте также:  Способ подвешивания техническая механика
Оцените статью
Разные способы