Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие_Вычисл техн и микропроц_Часть1_...doc
Скачиваний:
17
Добавлен:
04.05.2019
Размер:
3.06 Mб
Скачать

9.4.3 Циклічні програми

Вхідний контроль:

  1. Чи завжди у циклічній частині програми треба вказувати необхідну кількість повторень циклу?

  2. Наведіть приклади організації циклів за допомогою команд мови Асемблер і покажіть, як вони реалізуються.

Програми, у яких багаторазово виконуються ті ж самі ділянки обчислень, як правило, з різними значеннями вхідних даних, називаються циклічними, а послідовність команд, що повторюються, циклами. Цикли з наперед заданою кількістю повторень називаються арифметичними. Цикли, що не мають заздалегідь заданої кількості повторень, називаються ітераційними. Вихід з них відбувається при виконанні заданої умови. Для реалізації арифметичних циклів треба організувати лічильник циклів. За умовчанням для організації лічильника циклів призначений регістр СХ (ЕСХ у МП І80386 та старших). Якщо лічильник спадний, то при виконанні кожного циклу із його вмісту віднімається одиниця. Цикли повторюються доти, доки вміст лічильника буде більший за нуль. Циклічна програма вважається завершеною, якщо лічильник дорівнює нулю. Рідше використовуються зростаючі лічильники. При роботі з масивами закінчувати цикли можна також при досягненні поточної адреси елемента масиву адреси його останнього елемента. Як лічильник циклів можна використовувати будь-який регістр загального призначення, але у системі команд мови Асемблера існують спеціальні команди умовного переходу, в яких перевіряється вміст регістра СХ (ЕСХ).

Приклад 9.4.9 Перед записом байта даних у регістр передавача послідовного асинхронного адаптера RS-232-C треба перевірити, чи вільний є регістр зберігання передавача, тобто чи завершено передавання попереднього символу. Ознакою “порожнього” регістра зберігання є установлений в 1 п’ятий біт регістра стану лінії з адресою 3FDH. Наступний фрагмент програми реалізує цю перевірку у циклі:

MOV DX,3FDH ; Завантаження адреси регістра стану лінії

M1: IN AL,DX ; Введення байта стану лінії

AND AL,20H ; Регістр зберігання передавача

JZ M1 ; порожній, D5 = 1?

NOP

Приклад 9.4.10 Перед прийомом даних з порту приймача послідовного асинхронного адаптера RS-232-C треба перевірити, чи прийняте з лінії дане перебуває у буферному регістрі приймача. Ознакою цього є наявність 1 у нульовому біті регістра стану лінії з адресою 3FDH. Наступний фрагмент програми реалізує цю перевірку в циклі:

MOV DX,3FDH ; Завантаження адреси порту стану лінії

M1: IN AL,DX ; Введення байта стану лінії

AND AL,01H ; Перевірка наявності даного у буферному регістрі

; приймача

JZ M1 ; D0 = 1

Приклад 9.4.11 Знайти у чотириелементному рядку байт, що дорівнює 43Н, якщо рядок розміщений, починаючи з ефективної адреси 0200Н, а вміст сегментного регістра даних ES дорівнює 7000Н:

7000:0200 41 42 43 44.

Лічильник байтів у рядку організуємо у регістрі СL, ефективна адреса байтів вміщується в індексний регістр DI, а еталон шуканого байта завантажуємо до AL. Для перепускання неспівпадаючих елементів використовується префікс REPNZ.

MOV AX,7000H ;

MOV ES,AX ;

MOV CL,0004H ; Організація лічильника циклів

MOV DI,0200H ; Організація непрямого регістрового адресування

; елементів рядка

MOV AX,0043H ; Завантаження еталонного байта до AL

STD ; Установлення прапорця напрямку

CLD ; Скидання прапорця напрямку

REPNZ ; Організація перепускання неспівпадаючих елементів

SCASB ; Сканування байтів рядка

Програма виконується циклічно чотири рази, кожний цикл являє собою лінійну програму. Після сканування усіх байтів рядка в регістрі СХ буде записане число 0001Н, а в регістрі DI – число 0203Н, на одиницю більше, ніж адреса шуканого байта. Прапорець ZF установлюється після виконання програми.

Приклад 9.4.12 Одновимірний масив М(N), N = 10H однобайтових елементів зі знаками розміщений у сегменті даних, починаючи з ефективної адреси 20H; розсортувати елементи масиву на додатні М(P) та від’ємні М(NEG) і запам’ятати додатні елементи в області пам’яті MP, починаючи з ефективної адреси 30H, а від’ємні елементи в області пам’яті MNEG, починаючи з ефективної адреси 40H. Сегменти DS та ES суміщені.

Структурна схема алгоритму наведена на рис. 9.14.

Фрагмент програми розв’язання задачі.

MOV CX,0010H ; Завантаження лічильника циклів

MOV SI,0020H ; Завантаження адреси первісного масиву

MOV DI,0030H ; Завантаження початкової адреси масиву

; додатних елементів

MOV BX,0040H ; Завантаження початкової адреси масиву

; від’ємних елементів

СLD ; Виставлення автоінкрементування SI та DI

CYCLE: LODSB ; Виклик чергового елемента масиву

OR AL,AL ; Виставлення ознак елемента масиву

JS NEG ; Елемент є додатний?

Р: STOSB ; так, запис до масиву додатних чисел

JMP COUNT ; БП на команду перевірки лічильника

; циклів

NEG: MOV [BX],AL ; ні, запис до масиву чисел

INC BX ; Нарощування адреси масиву від’ємних

; чисел

COUNT: LOOP CYCLE ; Перевірка лічильника циклів

NOP

Рисунок 9.14 – Структурна схема алгоритму

Приклад 9.4.13 Знайти середнє арифметичне N двобайтових елементів масиву M(N), N = 10H, що вони зберігаються у пам’яті в доповняльному коді, починаючи з адреси 7000:0020. Результат розмістити за ефективною адресою 30Н. Структурна схема алгоритму подана на рис. 9.15.

Рисунок 9.15 – Структурна схема програми

Програма розв’язання задачі.

MOV AX,7000H ; Організація сегмента даних,

MOV DS,AX ; починаючи з ефективної адреси 7000:0000

MOV BX,0020Н ; Завантаження адреси початку масиву

MOV AX,0000H ; Обнулення акумулятора (S = 0)

M1: ADD AX,[BX] ; Додавання чергового елемента масиву

ADD BX,2 ; Нарощування адреси чергового елемента

; масиву

CMP BX,0030H ; Чи дорівнює адреса чергового елемента масиву

JNZ M1 ; адресі останього+2? Якщо ні, повернення на

; початок циклу

MOV BX,0010H ; Завантаження дільника до BX

IDIV BX ; Визначення середнього арифметичного

MOV [30H],AX ; Запам’ятовування середнього арифметичного

NOP

Сума елементів масиву вміщується в акумуляторі АХ, результат треба запам’ятовувати за ефективною адресою 30H.

Приклад 9.4.14 Написати підпрограму часової затримки тривалістю 100 мкс при умові, що тривалість такту 0,1 мкс. Для організації підпрограми затримки, яка найчастіше має назву DELAY, треба використати лічильник для зберігання числа повторень циклів, від якого залежить час затримки. Значення Х обчислюється за формулою

,

де дужки ] [ означають, що дрібна частина відкидається; tз – задане значення затримки; t0 – час, потрібний для одноразово виконуваних команд; tц – час, потрібний для виконання циклічно повторюваних команд. Вибір застосовуваних у підпрограмі команд та обчислення Х являє собою ітераційний процес, тривалість якого залежить від необхідної точності затримки. За наявності високих вимог до точності забезпечуваної затримки можливі два шляхи розв’язання цієї задачі:

1) зменшують отримане значення Х на кілька одиниць, а отримане зменшення компенсують командою NOP, яка виконується багаторазово;

2) змінюють значення tц за рахунок включення у цикл інших команд.

Наступний фрагмент підпрограми DELAY дає уявлення про принцип програмної реалізації часової затримки:

CALL DELAY ; 19 тактів при умові внутрішньосегментного

; переходу

DELAY: MOV AL,X ; 2 такти, Х обчислюється за формулою та

; задається у команді з безпосереднім

; адресуванням

TIME: DEC AL ; 3 такти

JNZ TIME ; 8 тактів

NOP ; 2 такти

RET ; 8 тактів

На початку підпрограми DELAY, як і в кожній підпрограмі, треба запам’ятати вміст використовуваних регістрів та регістра прапорців:

CALL DELAY ; 19 тактів

DELAY: PUSH BX ; 11тактів

PUSHF ; 10 тактів

MOV BL,X ; 2 такти, Х повинен завантажуватись у BL

; як операнд з безпосереднім адресуванням

M1: DEC BL ; 3 такти

JNZ M1 ; 16 тактів

POP F ; 8 тактів

POP BX ; 8 тактів

RET ; 8 тактів

t0 = (19+11+10+2+8+8+8)·0,1 = 7,3 мкс;

tц = (3+16)·0,1 = 1,9 мкс;

tз = 100 мкс.

При Х = 49D отримаємо tз = 6,6 + 49 * 1,9 = 6,6 + 93,1 = 99,7 мкс.

Така точність формування затримки не є достатня і тому до одноразово виконуваних команд треба додати команду, яка б займала 3 такти і виконувалась 0,3 мкс. Це може бути команда OR BL, BL. Остаточно фрагмент підпрограми затримки має вигляд:

DELAY: PUSH BX

PUSHF

MOV BL,31Н

M1: DEC BL

JNZ M1

OR BL,BL

POP F

POP BX

RET

Слід зазначити, що доцільно перед зверненням до підпрограми DELAY заборонити масковані переривання від зовнішніх пристроїв і наступною після команди CALL DELAY вжити команду дозволу переривань.

Контрольні запитання:

  1. Які програми називаються циклічними?

  2. Які види циклічних програм ви знаєте?

  3. Які команди умовних переходів використовуються для пошуку в рядку першого нульового або ненульового елемента?

  4. Який спосіб адресування використовується при роботі з двовимірними масивами?

  5. У масиві N однобайтових чисел, розміщених у пам’яті, починаючи з адреси 7000: 0010Н, підрахувати суму парних чисел. Результат розмістити за зміщенням 0027Н.

  6. У масиві M(N) однобайтових чисел, розміщених у пам’яті, починаючи з адреси 7000: 0010Н, підрахувати суму непарних чисел. Результат розмістити за зміщенням 0022Н.

  7. У масиві M(N) однобайтових чисел, розміщених у пам’яті, починаючи з адреси 7000:0010Н, підрахувати кількість непарних чисел. Результат розмістити за зміщенням 0030Н.

  8. У масиві М(N) двобайтових чисел, розміщених у пам’яті, починаючи з адреси 7000:0010Н, підрахувати кількість парних чисел. Результат розмістити за зміщенням 0026Н.

Контрольні запитання підвищеної складності:

    1. Знайти суму елементів головної діагоналі квадратної матриці NN і розмістити результат за зміщенням 0020H. Початкова адреса двовимірного масиву 7000:0010.

    2. Скільки разів буде повторено цикл, якщо у лічильних циклів CL буде спочатку занесено число 2?