К о м а н д ы

ц и к л о в

Команды циклов LOOPx

Группа команд условного перехода LOOPх служит для организации циклов в программах. Все команды цикла используют регистр CX в качестве счетчика цикла. Простейшая из них – команда LOOP. Она уменьшает содержимое CX на 1 и передает управление на указанную метку, если содержимое CX не равно 0. Если вычитание 1 из CX привело к нулевому результату, выполняется команда, следующая за LOOP.

Синтаксис:LOOP короткая метка
Логика работы:
СХ = Counter
short_label:
; Выполнение тела цикла
СХ = СХ - 1
if (СХ != 0) goto short_label


Аналог реализации команды LOOP на Ассемблере:
MOV СХ, Counter
short_label:
; Выполнение тела цикла
; Проверка условия ПРОДОЛЖЕНИЯ цикла

DEC СХ
СМР СХ, 0
JNE short_label


Команда LOOP уменьшает содержимое регистра СХ на 1, затем передает управление метке shorMabel, если содержимое СХ не равно 0. Передача управления на метку shortjabel для базовых процессоров — только КОРОТКАЯ[-128,0]. Поскольку условие выхода из цикла проверяется в КОНЦЕ, при значении Counter=0 цикл все равно выполнится. Этого мало, мы еще и зациклимся. Чтобы этого избежать, обычно ДО НАЧАЛА ЦИКЛА проверяют содержимое регистра СХ на ноль. Таким образом, стандартная последовательность команд для организации цикла СО СЧЕТЧИКОМ имеет следующий вид:

MOV CX, Counter
JCXZ ExitCicle                         ; если CX = 0, цикл ОБОЙТИ
short_label:
; Выполнение тела цикла
LOOP short_label
ExitCicle:


Пример:Вычислить значение факториала р = n! = 1*2*3*...*n
Известно, что 0! = 1. Отрицательным значение n быть НЕ может.

.Model Large,С
; определение префикса для локальных меток
locals @@
.code
Extrn С n: Word
Extrn С p: Word
Public proizv1
Proizv1 Proc far                       ; Вариант 1
mov cx,n                                        ; количество повторений
mov si,1
mov ax,si
jcxz @@Exit                                ; if cx=0 then Exit
@@begin:                                     ; = НАЧАЛО цикла =
mul si                                                ; < dx:ax > = < ax >*< si >
inc si
; ==== Выход из цикла ==================
loop @@begin
@@Exit:
mov p,ax
ret
proizv1 endp
Public proizv2
Proizv2 Proc far                       ; Вариант 2
mov cx ,n                                      ; количество повторений
mov ax,1
jcxz @@Exit                                ; if cx=0 then Exit
@@begin:                                     ; = НАЧАЛО цикла =
mul cx                                              ; < dx:ax > = < ax >*< cx >
; ==== Выход из цикла =========

loop @@begin
@@Exit:
mov p,ax ret
proizv2 endp end

Директива locals

Директива locals позволяет нам не думать о дублировании имен меток в разных подпрограммах. Метки с префиксом @@ считаются локальными. Если компилятор встретит метку с таким же именем, он просто при компиляции присвоит ей другое имя (обычно эти метки получают в конце имени номер, который увеличивается на единицу — все очень просто!).

Команда LOOPE (LOOPZ)

Команда LOOPE (LOOPZ) переход по счетчику и если равно.
Данная команда имеет два равнозначных мнемонических имени (if Equal — если Равно или if Zero — если Ноль).

Синтаксис команды:
LOOPE короткая_метка
LOOPZ короткая_метка


Логика работы команды:
СХ = Counter
Short_Label:; Выполнение тела цикла
СХ = СХ - 1
if (СХ != 0 && ZF = 1) goto Short_Label


Все то, что говорилось для команды LOOP, справедливо и для команды LOOPE (LOOPZ), добавляется еще проверка флага ZF. Применяется данная команда в случае, если нужно досрочно выйти из цикла, как только находится ПЕРВЫЙ элемент, ОТЛИЧНЫЙ от заданной величины.

Команда LOOPNE (LOOPNZ)

Команда LOOPNE (LOOPNZ) переход по счетчику и если НЕ равно.
Данная команда тоже имеет два равнозначных мнемонических имени (if Not Equal — если НЕ равно или if Not Zero — если НЕ ноль). В отличие от предыдущей команды проверяется, сброшен ли флаг нуля ZF=0.

Синтаксис команды:
LOOPNE короткая метка
LOOPNZ короткая_метка


Логика работы команды:
СХ = Counter
shortlabel: ; Выполнение тела цикла
СХ = СХ - 1
if (СХ != 0 && ZF == 0) goto shortlabel


Все то, что говорилось для предыдущей команды, справедливо и для команды LOOPNE (LOOPNZ). Применяется данная команда в случае, если нужно досрочно выйти из цикла, как только находится ПЕРВЫЙ элемент, РАВНЫЙ заданной величине. Пример:Вычислить значение суммы чисел натурального ряда: s = 1+2+3+...+n. Вычисления закончить, как только значение суммы станет равным некоторому числу k или не будут перебраны все n чисел.

Extrn С n:Word
Extrn С s:Word
Extrn С k:Word
Public sum
sum Proc far
mov cx,n                                      ; количество повторений
xor ax, ax
xor si, si
jcxz @@Exit                              ; if cx=0 then Exit
@@begin:                                   ; = НАЧАЛО цикла =
inc si
add ax, si
cmp ах,k
; =Выход из цикла, если ax=k или сх=0
loopNE @@begin
@@Exit:
mov s,ax
ret
sum endp


Программирование на Машинно-Ориентированных Языках.
Преподаватель: Коробов С.А.