Листинг 10.3. Подсчет нулевых байтов с использованием команд
управления циклом
<1>
<2> model small
<3>
100h
<4>
<5>
10
элементов в mas
<6> mas db
<7>
<8> start:
<9> mov
<10> mov
<11> mov
;длину поля mas в сх
<12> xor
<13> xor
<14> jcxz exit
сх на 0, если 0, то выход
<15>
<1б> cmp
;сравнить очередной элемент mas с 0
<17> jne ml ;если не равно 0, то на ml
<18> inc
;в
- счетчик нулевых элементов
<19> ml:
<20> inc si
к следующему элементу
<21> loop cycl
<22> exit:
продолжение
232 Глава 10. Команды передачи управления
Листинг
<23>
<24> i n t 21h ;возврат управления операционной системе
<25> end start
Заметьте, что у команды
в строке 14 осталась только одна функция — не
допустить выполнения «пустого» цикла, поэтому несколько изменилось ее место
в тексте программы: теперь она стоит перед меткой начала цикла
Изменение
и контроль содержимого регистра СХ в процессе выполнения каждой итерации вы-
полняет команда ШОР (строка 21).
Рассмотрим пример, в котором продемонстрируем типичный подход к исполь-
зованию команды LOOPNZ. В программе из листинга 10.4 ищется первый нулевой
элемент в поле mas. Интерес представляют строки 20 и 21. Команда LOOPNZ на ос-
содержимого регистра СХ и флага ZF принимает решение о продолжении
цикла. Выход из цикла происходит в одном из двух случаев: СХ = 0
все элементы поля mas) или ZF 1 (командой СМР обнаружен нулевой элемент).
Назначение следующей команды
(строка 21) в том, чтобы распознать конкрет-
ную причину выхода из цикла. Если выход из цикла произошел после просмотра
строки, в которой нет нулевых элементов, то флаг JZ не сработает и будет выдано
сообщение об отсутствии нулевых элементов в строке (строки 7, 23-25). Если вы-
ход из цикла произошел в результате обнаружения нулевого элемента, то в регис-
тре SI окажется номер позиции этого элемента в поле mas и при необходимости
можно продолжить обработку. В нашем случае мы просто завершаем программу —
переходим на метку exit.
Листинг
Пример использования команды loopnz
<1>
<2> model small
<3>
<4>
<5>
10 ;количество элементов в mas
<6> mas
<7> message db "В поле mas нет
равных
<8>
<9> start:
<10> mov
<11> mov
<12> mov
;длину поля mas в сх
<13> xor
<14> xor
<15>
exit ;проверка сх на
если 0, то выход
<1б> mov
si к адресации элементов поля mas
<17> cycl:
<18> inc si
<19> cmp
;сравнить очередной элемент mas с 0
<20> loopnz cycl
<21> jz
причины выхода из цикла
сообщения, если нет нулевых элементов в mas
<23> mov
<24> mov
message
<25> int 21h
<26> exit:
<27> mov
<28> int 21h ;возврат управления операционной системе
<29> end start
Организация циклов 233
Читатели, имеющие даже небольшой опыт программирования на языках высо-
кого уровня, знают, что очень часто возникает необходимость во вложенных цик-
лах. Самый простой пример — обработка двухмерного массива. Работу с массива-
ми, в том числе двухмерными, мы рассмотрим в главе 13, пока же разберемся
с основными принципами организации вложенных циклов. Основная проблема,
которая при этом возникает, — как сохранить значения счетчиков в регистре ЕСХ/
СХ для каждого из циклов. Для временного сохранения счетчика внешнего цикла
на время выполнения внутреннего доступно несколько способов: задействовать
регистры, ячейки памяти или стек. В следующем фрагменте программы имеется
три цикла, вложенные один в другой. Этот фрагмент можно рассматривать как
шаблон для построения других программ с вложенными циклами.
<2> mov
количество повторений цикла cycl_l
<3> cycl_l:
<4> push сх ;счетчик цикла cycl_l в стек
<5>
команды цикла cycl_l
<6> mov
количество повторений цикла cycl_2
<7> c y c l _ 2 :
<8> push сх ;счетчик цикла cycl_2 в стек
<9>
цикла cycl_2
<10> mov
количество повторений цикла cycl_3
<11> cycl_3:
<12>
цикла cycl_3
<13> loop cycl_3
<14>
цикла cycl_2
<15> pop сх
счетчик цикла cycl_2
<1б> loop cycl_2
<17>
цикла cycl_l
<18> pop сх
счетчик цикла cycl_l
<19> loop cycl_l
<20>
В качестве примера рассмотрим фрагмент программы, которая обрабатывает
специальным образом некоторую область памяти (листинг 10.5). Область памяти
рассматривается как совокупность пяти полей, содержащих 10 однобайтовых эле-
ментов. Требуется заменить все нулевые байты в этой области значением
Листинг
Пример использования вложенных циклов
<1>
<2> model small
<3>
<4>
<5> mas
db
db 1,0,9,8,0,7,8
db 1,0,9,8,0,7,8
db 1,0,9,8,0 7
db 1
7
. code
start:
mov
mov
xor
lea
mov
push
xor
,0,2
,0,2
?
?
,0
,0
,0
0
0
продолжение
5>4>3>2>1>20>19>18>17>15>14>13>12>11>10>9>8>7>6>5>4>3>2>29>28>27>26>25>24>23>21>20>19>18>17>15>14>13>12>11>10>9>8>7>6>5>4>3>2>1>25>24>23>22>21>20>19>18>17>15>14>13>12>11>10>9>8>7>6>5>4>3>2>1> Do'stlaringiz bilan baham: |