Лекция 11. Организация цикл используя команды сравнения и условного перехода.




С помощью команд перехода можно реализовать любые разветвления и циклы.Например, следующие операторы языка Паскаль

a. if X>0then SI else S2

b. while X>0 do S

c. repeat S until X>0

где S, SI и S2 - какие-то операторы, а X - знаковая переменная, реализуются по таким схемам (соответственно):

Среди циклов на практике наиболее часто встречаются циклы с заранее известным числом повторений (for-циклы языка Паскаль), поэтому в систему команд многих ЭВМ обычно включают дополнительные команды, упрощающие реализацию подобных циклов и называемые командами управления циклом. Есть такие команды и в ПК, их мы сейчас и рассмотрим.

Пример 2

А, В и С - переменные размером в слово, причем А>0 и В>0. Требуется записать в С наибольший общий делитель чисел А и В: С=НОД(А,В).

Решение

Для нахождения НОД двух чисел воспользуемся алгоритмом Евклида в следующем варианте: пока эти числа не равны, надо вычитать из большего числа меньшее, а когда они сравняются, то это и будет НОД исходных чисел. (Замечание: этот алгоритм можно применять только к строго положительным числам, иначе он зациклится.)

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

Пример 3

К - байтовая переменная со значением от 1 до 18. Требуется записать в регистр AL количество двузначных десятичных чисел (от 10 до 99), сумма цифр которых равна К.

Решение

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

for dh:*l to 9 do

for dl:=0 to 9 do

if dh+dl=k then =al+l

Для организации обоих циклов мы будем использовать команду LOOP. Но это значит, что каждый из циклов должен использовать регистр СХ как свой счетчик цикла, поэтому циклы будут "мешать" друг другу, будут портить значение СХ другого цикла. Устранить эту неприятность можно следующим образом: перед началом выполнения внутреннего цикла надо спасти где-то (например, в другом регистре) значение СХ, соответствующее внешнему циклу, и затем использовать СХ для организации внутреннего цикла, а по его окончанию надо восстановить в СХ прежнее значение.

С учетом всего сказанного наша задача решается так:

 

Лекция 12.

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

Содержание: Команда LOOP. Команды LOOPE/LOOPZ и LOOPNE/LOOPNZ. Примеры

Краткое содержание лекции:

Команда 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 Нарушение авторских прав и Нарушение персональных данных


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