Ассемблер Это просто! Учимся программировать

       

Создание циклов.


Что такое цикл? Допустим, нам нужно выполнить некоторый код программы несколько раз. Возьмем, к примеру, вывод строки функцией 09h прерывания 21h:

Пример 1

mov ah,9 mov dx,offset Str int 21h mov ah,9 mov dx,offset Str int 21h mov ah,9 mov dx,offset Str int 21h

Этот участок кода выведет 3 раза на экран некую строку Str. Код получается громоздким, неудобно читать. Размер программы разрастается... Для выполнения подобных примеров используется оператор loop (вспоминаем, как мы оформляем новые операторы):

Команда Перевод (с англ.) Назначение Процессор
LOOP метка loop - петля Организация циклов 8086



Количество повторов задается в регистре CX (счетчик). Вот как можно использовать этот оператор на практике (изменим ):

Пример 2:

(1) mov cx,3 (2) Label_1: (3) mov ah,9 (4) mov dx,offset Str (5) int 21h (6) loop Label_1 (7) ...

В строке (1) загружаем в CX количество повторов (отсчет будет идти от 3 до 0). В строке (2) создаем метку (Label - метка). Далее (строки (3)-(5)) выводим сообщение. И в строке (6) оператор loop уменьшает на единицу CX и, если он не равен нулю, переходит на метку Label_1 (строка (2)). Итого строка будет выведена на экран три раза. Когда программа перейдет на строку (7), регистр CX будет равен нулю. В результате код программы уменьшается почти в три раза по сравнению с Примером 1.

Удобно? Без вопросов!

Тренироваться будем на практике, а теперь следующий оператор:

Команда Перевод (с англ.) Назначение Процессор
JMP метка jump - прыжок Безусловный переход 8086

Команда jmp просто переходит на указанную метку в программе: (1) mov ah,9 (2) mov dx,offset Str (3) int 21h (4) jmp Label_2 (5) (6) add cx,12 (7) dec cx (8) Label_2: (9) int 20h

В результате строки (5) - (7) работать не будут. Программа выведет сообщение на экран, а затем jmp перейдет к строке (8), после чего программа завершится.

Команда Перевод (с англ.) Назначение Процессор
DEC приемник decrement - декремент Уменьшение на 1 8086

Оператор dec уменьшает значене приемника на 1:

mov ah,12 ; загружаем в AH число 12 dec ah ; теперь AH=11

С помощью данного оператора можно также создавать циклы, которые будут работать быстрее оператора loop. Следующий пример будет работать также, как , только чуть-чуть быстрее:

Пример 3:

(1) mov cx,3 (2) Label_1: (3) mov ah,9 (4) mov dx,offset Str (5) int 21h (6) dec cx (7) jnz Label_1

Не обращайте внимание на строку (7). Мы ее рассмотрим позже. Я привел этот пример для того, чтобы показать, что один и тот же прием в Ассемблере можно выполнить разными операторами. И чем лучше программист владеет ими, тем компактнее и быстрее программа будет работать. Поэтому и получается, что разные программисты пишут на одном языке, но скорость и объем программы разные. В процессе обучения, я буду также учить вас оптимизировать программы.



Содержание раздела