Короткі теоретичні відомості. Мета роботи: ознайомитися зі структурою та реалізацією циклів в програмі

ЛАБОРАТОРНА РОБОТА №6

КОМАНДИ ПЕРЕСИЛКИ ДАНИХ. ОЗНАЙОМЛЕННЯ З РОБОТОЮ ЦИКЛІВ

Мета роботи: ознайомитися зі структурою та реалізацією циклів в програмі.

 

Короткі теоретичні відомості

Цикли, що дозволяють виконати деяку ділянку програми багаторазово, в будь-якій мові є однією з найбільш уживаних конструкцій. У системі команд МП 86 цикли реалізуються, головним чином, за допомогою команди loop (петля), хоча є й інші способи організації циклів. У більшості випадків число кроків в циклі визначається вмістом регістра СХ, тому максимальне число кроків складає 64 К.

Організація циклічних переходів, як на мовах високого рівня, так і мовою assembler являє собою чудовий засіб, що дозволяє значно знизити код виконуваної програми.

У загальному вигляді будь цикл записується в асемблері як умовний перехід.

 

Організація циклу за допомогою команди LOOP (Перший спосіб)

Команда loop (анг. петля) виконує декремент вмісту регістра СХ (лічильник), і якщо воно не дорівнює 0, здійснює перехід на вказану мітку вперед або назад в тому ж програмному сегменті в діапазоні - 128 ... + 127 байт. Зазвичай мітка поміщається перед першою пропозицією тіла циклу, а команда loop є останньою командою циклу. Вміст регістра СХ розглядається як ціле число без знака, тому максимальне число повторень групи включених в цикл команд складає 65536 (якщо перед входом у цикл СХ = 0). Команда не діє на прапорці процесора.

Команда Призначення Процесор
LOOP мітка Організація циклів

Простий приклад організації циклічного переходу (з лічильником в регістрі cx) на мові Assembler:

. model tiny ; модель пам’яті, в якій сегменти коду, даних і стека об’єднані.
. code ; сегмент кода, який містить дані.
org 100h ; початок СОМ-файла
begin: ; мітка початку кода програми
mov cx,10 ; завантажуємо в (регістр-лічильник) CX кількість повторів (відлік буде йти від 10 до 0)
Label1: ; створюємо мітку (Label - мітка).
mov ah,9 ; поміщаємо номер функції DOS "виведення рядка (9)" в регістр АН.
mov dx, offset String ;поміщає в регістр DX зсув мітки String щодо початку сегменту даних
int 21h ; функція DOS "виведення строки"
loop Label1 ; оператор loop зменшує на одиницю CX і, якщо він не дорівнює нулю, переходить на мітку Label1 (рядок 6)
ret ; функція DOS "завершити програму"
string db 'privet $' ; cтрока, яка містить дані для виведення
end begin ; мітка завершення кода програми

 

У рядку (5) завантажуємо в CX кількість повторів (відлік буде йти від 10 до 0). У рядку (6) створюємо мітку (Label - мітка). Далі (рядки (7) - (9)) виводимо повідомлення. І в рядку (10) оператор loop зменшує на одиницю CX і, якщо він не дорівнює нулю, переходить на мітку Label1 (рядок (6)). Таким чином, рядок буде виведена на екран десять разів. Коли програма перейде на рядок (11), регістр CX буде дорівнює нулю.

 

Організація циклу за допомогою команди JMP (Другий спосіб)

Команда jmp передає управління у вказану точку того ж або іншого програмного сегмента. Адреса повернення не зберігається. Команда не впливає на прапори процесора.

Команда jmp має п’ять різновидів:

1. перехід прямої короткий (у межах - 128 ... + 127 байтів);

2. перехід прямої ближній (в межах поточного програмного сегменту);

3. перехід прямої дальній (у інший програмний сегмент);

4. перехід непрямий ближній;

5. перехід непрямий дальній.

 

Всі різновиди переходів мають одну і ту ж мнемоніку jmp, хоча і розрізняються коди операцій. У багатьох випадках транслятор може визначити вид переходу по контексту, в тих же випадках, коли це неможливо, слід використовувати атрибутні оператори (short - прямий короткий перехід; near ptr - прямий ближній перехід; far ptr - прямий дальній перехід; word ptr - непрямий ближній перехід; dword ptr - непрямий дальній перехід).

Команда Призначення Процесор
JMP мітка Безумовний перехід

 

. model tiny ; модель пам'яті, в якій сегменти коду, даних і стека об'єднані.
. code ; сегмент коду, який містить дані.
org 100h ; початок СОМ-файла
begin: ; мітка початку кода програми
label1: ; створюємо мітку
mov ah,9 ; поміщаємо номер функції DOS "виведення рядка (9)" в регістр АН.
mov dx,offset String ; поміщає в регістр DX зсув мітки String щодо початку сегменту даних
int 21h ; функція DOS "виведення строки"
jmp Label1 ; перехід на строку з міткою Label1
add cx,12 ; подати до значення регістра cx число 12
dec cx ; зменшити значення регістра cx на 1
ret ; функція DOS "завершити програму"
string db "PRIVET",13,10,'$' ; cтрока, яка містить дані для виведення
end begin ; мітка завершення кода програми

 

В результаті роботи програми буде зациклений блок рядків (6) - (10) (Виведення рядка PRIVET численна кількість разів) Рядки (10) - (11).

 

Організація циклу за допомогою команди DEC і JNZ (Третій спосіб)

За допомогою цих операторів можна створювати цикли, які будуть працювати швидше оператора Loop. Комбінована робота команд DEC і JNZ зменшує вміст регістра CX на 1 і виконує перехід на мітку, якщо в CX не дорівнює нулю.

Команда DEC, крім того, встановлює прапорець нуля у регістрі прапорців в стан 0 або 1. Команда JNZ потім перевіряє цю установку.

Аналогічно командам JMP і LOOP операнд в команді JNZ містить значення відстані між кінцем команди JNZ і адресою переходу (Label 1), яке додається до командного покажчику. Ця відстань повинна бути в межах від - 128 до +127 байт.


 

. model tiny ; модель пам'яті, в якій сегменти коду, даних і стека об'єднані.
. code ; сегмент коду, який містить дані.
org 100h ; початок СОМ-файла
begin: ; мітка початку кода програми
mov cx,10 ; Завантажуємо в (регістр-лічильник) CX кількість повторів (відлік буде йти від 10 до 0)
Label1: ; створюємо мітку (Label - мітка).
mov ah,9 ; поміщаємо номер функції DOS "виведення рядка (9)" в регістр АН.
mov dx,offset String ; поміщає в регістр DX зсув мітки String щодо початку сегменту даних
int 21h ; функція DOS "виведення строки"
dec cx ; оператор DEC зменшує на одиницю CX і, якщо він не дорівнює нулю, переходить на мітку Label1
jnz Label1 ; умовний перехід на строку з міткою Label1
ret ; функція DOS "завершити програму"
string db 'priver ',13,10, '$' ; cтрока, яка містить дані для виведення
end begin ; мітка завершення кода програми

 

Програма для практики

Напишемо програму, яка виводить на екран всі ASCII-символи (16 строк по 16 символів в строчці).

. model tiny ; модель пам'яті, в якій сегменти коду, даних і стека об'єднані.
. code ; сегмент коду, який містить дані.
org 100h ; початок СОМ-файла
begin: ; мітка початку кода програми
mov cx,256 ; задаємо значення лічильника (256 символів)
mov dl,0 ; перший символ - з кодом 00
mov ah,2 ; номер функції DOS "виведення символу"
cloop: int 21h ; виклик DOS
inc dl ; збільшення DL на 1 – наступний символ
test dl,0Fh ; якщо DL не кратний 16
jnz continue_loop; ; продовжити цикл,
push dx ; інакше: зберегти поточний символ
mov dl,0Dh ; вивести CR
int 21h ; виклик DOS
mov dl,0Ah ; вивести LF
int 21h ; виклик DOS
pop dx ; відновити поточний символ
continue_loop: ; мітка
loop cloop ; продовжити цикл
ret ; завершення СОМ-файла
end begin ; мітка завершення кода програми

 

Тут за допомогою команди LOOP оформляється цикл, що виконується 256 раз (значення регістра СХ на початку циклу). Регістр DL містить код символу, який дорівнює нулю на початку циклу і збільшується кожного разу на 1 командою INC DL. Якщо значення DL відразу після збільшення на 1 кратне 16, воно тимчасово зберігається в стеку і на екран виводяться символи CR і LF, що виконують перехід на початок нового рядка. Перевірка виконується командою TEST DL, 0Fh - результат операції AND над DL і 0Fh буде нулем, тільки якщо молодші чотири біта DL дорівнюють нулю, що і відповідає кратності шістнадцяти.

 

Зміст звіту

3.1 Титульний лист.

3.2 Індивідуальний варіант завдання.

3.3 Тестові набори даних і передбачувані результати.

3.4 Текст програми до налагодження.

3.5 Список помилок, виявлених при налагодженні.

3.6. Результати виконання тестів.

3.7. Роздруківка лістингу компіляції налагодженої програми із зазначенням роботи кожного рядка.

 

Завдання для виконання

4.1 Виконайте всі приклади, що містяться в описі даної лабораторної роботи.

4.2 Проаналізуйте роботу програми прикладу для практики.

4.3 Вивчити умови організації циклічних переходів на мові Асемблера.

4.4 Напишіть програму, що виводить на екран слово "!!!! Hello!!!!" використовуючи команди циклічних переходів (3 варіанти).

4.5 Отримайте заданий від викладача (один з варіантів в табл. 1) і, користуючись правилами оформлення асемблерних програм, створіть програму, що виводить на екран слово, D число раз.

4.6 Програму ассемблюйте в файл типу *. Com або *. Exe (на вибір);

Відповіді на контрольні запитання:

1) Команда loop (анг. петля) виконує декремент вмісту регістра СХ (лічильник), і якщо воно не дорівнює 0, здійснює перехід на вказану мітку вперед або назад в тому ж програмному сегменті в діапазоні - 128 ... + 127 байт. Зазвичай мітка поміщається перед першою пропозицією тіла циклу, а команда loop є останньою командою циклу. Вміст регістра СХ розглядається як ціле число без знака, тому максимальне число повторень групи включених в цикл команд складає 65536 (якщо перед входом у цикл СХ = 0). Команда не діє на прапорці процесора.

2) У більшості випадків число кроків в циклі визначається вмістом регістра СХ.

3) Максимальне число кроків складає 64 К.

4) Команда jmp передає управління у вказану точку того ж або іншого програмного сегмента. Адреса повернення не зберігається. Команда не впливає на прапори процесора.

5) Команда jmp має п’ять різновидів:

1. перехід прямої короткий (у межах - 128 ... + 127 байтів);

2. перехід прямої ближній (в межах поточного програмного сегменту);

3. перехід прямої дальній (у інший програмний сегмент);

4. перехід непрямий ближній;

5. перехід непрямий дальній.

Всі різновиди переходів мають одну і ту ж мнемоніку jmp, хоча і розрізняються коди операцій. У багатьох випадках транслятор може визначити вид переходу по контексту, в тих же випадках, коли це неможливо, слід використовувати атрибутні оператори (short - прямий короткий перехід; near ptr - прямий ближній перехід; far ptr - прямий дальній перехід; word ptr - непрямий ближній перехід; dword ptr - непрямий дальній перехід).

6) За допомогою цих операторів можна створювати цикли, які будуть працювати швидше оператора Loop. Комбінована робота команд DEC і JNZ зменшує вміст регістра CX на 1 і виконує перехід на мітку, якщо в CX не дорівнює нулю.

Команда DEC, крім того, встановлює прапорець нуля у регістрі прапорців в стан 0 або 1.

Команда JNZ потім перевіряє цю установку.

Аналогічно командам JMP і LOOP операнд в команді JNZ містить значення відстані між кінцем команди JNZ і адресою переходу (Label 1), яке додається до командного покажчику. Ця відстань повинна бути в межах від - 128 до +127 байт.

Варіант 26:флеш пам’ять

 

Рис 1

Рис 2

Рис 3

Рис 4

Рис 5

Рис 6

Рис 7

Рис 8