Для организации циклов имеются три команды LOOP (от англ. LOOP – описывать петлю), LOOPZ (от англ. LOOP while Zero – цикл пока ноль) и LOOPNZ (от англ. Loop while Not Zero – цикл пока не ноль), использующие в качестве счетчика цикла регистр CX. Формат команд приведен на рис.9.6.
Рис. 9.6. Формат команды организации цикла
Команда LOOP производит уменьшение значения в регистре CX на единицу и сравнение значения этого регистра с нулем:
– если СХ > 0, то управление передается на метку перехода;
– если CX = 0, то управление передается на следующую после LOOP команду.
Команда LOOPZ производит уменьшение значения в регистре CX на единицу, сравнение значения этого регистра с нулем и анализ флага нуля ZF:
– если СХ > 0 и ZF = 1, то управление передается на метку перехода;
– если CX = 0 или ZF = 0, то управление передается на следующую после LOOPZ команду.
Команда LOOPNZ производит уменьшение значения в регистре CX на единицу, сравнение значения этого регистра с нулем и анализ флага нуля ZF:
– если СХ > 0 и ZF = 0, то управление передается на метку перехода;
– если CX = 0 или ZF = 1, то управление передается на следующую после LOOPNZ команду.
Например, цикл в десять итераций:
MOV CX,10;Десять итераций цикла
m1: MOV AX,12
…
LOOP m1;Возврат на начало цикла
Необходимо отметить, что команды LOOP, LOOPZ и LOOPPNZ позволяют реализовывать только короткие циклы (в пределах –128…+127 байт).
При необходимости программировать вложенные циклы (цикл в цикле), значение одного из счетчиков можно сохранять в стеке:
MOV CX,30;Тридцать итераций главного цикла
cykl_1:
PUSH CX
…
MOV CX,5;Пять итераций вложенного цикла
cykl_2:
…
LOOP cykl_2
POP CX
LOOP cykl_1
Рассмотрим COM-программу, которая в заданном массиве букв латинского алфавита заменяет все строчные (малые) буквы на прописные (большие). Коды ASCII для английских символов приведены в табл.4.2. Строчным буквам соответствует диапазон кодов 61H…7AH, а прописным – 41H…5AH. Следовательно, если взятый из массива символ имеет код, не входящий в диапазон 61H…7AH, то он уже является прописной буквой и замену производить не нужно.
Для самого преобразования рассмотрим, что представляют собой ASCII коды символов в двоичном виде:
A = 41H = 01000001B,
a = 61H = 01100001B,
Z = 5AH =01011010B,
z = 7AH = 01111010B.
Как видим, отличие заключается лишь в пятом бите, который у строчных букв равен единице, а у прописных – нулю. Для преобразования строчных букв в прописные этот бит необходимо сбросить, например, командой AND.
Текст программы приведен на рис.9.7.
codesg SEGMENT PARA 'Code'
ASSUME CS:codesg,DS:codesg,SS:codesg,ES:nothing
ORG 100H
begin: JMP main
;-----------------------------------------------------
pole DB 'Hsd1fAbcVVxX4'
len=$-pole;Длина массива
;-----------------------------------------------------
main PROC NEAR
MOV CX,len;Число итераций
LEA BX,pole;Адрес массива в регистр BX
m1: MOV AL,byte ptr [BX];Чтение из массива
CMP AL,61H
JB next
CMP AL,7AH
JA next
AND AL,11011111B;Замена строчных на прописные
MOV byte ptr [BX],AL;Запись обратно в массив
next: INC BX;Следующий элемент массива
LOOP m1
MOV AX,4C00H;Можно использовать команду RET
INT 21H
main ENDP
codesg ENDS
END begin
Рис. 9.7. Программа замены в массиве строчных букв на прописные
Вопросы для самопроверки
1. Будет ли в данном фрагменте программы выполняться переход на метку m1?
MOV AL,35H
CMP AL,10110011B
JA m1
2. Будет ли в данном фрагменте программы выполняться переход на метку m1?
MOV AL,-35D
CMP AL,10111001B
JL m1
3. Будет ли в данном фрагменте программы выполняться переход на метку m1?
MOV AL,FEH
AND AL,00H
JZ m1
4. Сколько итераций будет у цикла при выполнении данного фрагмента программы?
MOV AX,5
MOV CX,4
m1: ADD AX,2
INC CX
LOOP m1
5. Чему будет равно значение регистра BL после выполнения данного фрагмента программы?
MOV BL,0
MOV CX,10
m2: INC BL
INC BL
m1: INC BL
LOOP m1
LOOP m2
6. Написать на языке ассемблера COM-программу, которая в заданном символьном массиве произвольной длины заменяет прописные (большие) латинские буквы на строчные (малые).
7. Написать на языке ассемблера программу типа COM, которая в заданном символьном массиве произвольной длины определяет количество прописных латинских букв и цифр.