Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lab_1-3.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
997.89 Кб
Скачать

1.2. Команди обробки рядкових даних мови асемблера

Раніше ми розглядали лише команди, які обробляли один байт або єдине слово. Але часто-густо при програмуванні необхідно розглядати дані великої довжини, зрівнювати їх, проводити над ними логічні та арифметичні операції. У кінці попереднього розділу ми з’ясували, що для обробки чисельних даних, що представлені у форматі ASCII, нам необхідно обробляти послідовно велику кількість байтів (залежно від розрядності числа). Такі саме проблеми стають і при обробці великих масивів текстової інформації, наприклад при її сортуванні. Як вам відомо, елементи такого формату називаються рядковими даними. Вони можуть містити літери, цифри, будь-які інші символи, і для їх обробки вживають особливі команди та алгоритми. В мові асемблера існує п’ять команд, призначених для обробки рядків:

MOVS -

Переслати один байт або єдине слово з однієї області пам’яті до іншої;

LODS -

Завантажити з комірки пам’яті один байт до регістру AL або слово до регістру AX;

STOS -

Записати вміст регістру AL або AX до комірки пам’яті;

CMPS -

Порівняти вміст двох комірок пам’яті розміром 1 байт або одне слово;

SCAS -

Порівняти вміст регістру AL або AX з вмістом відповідної комірки пам’яті

Як бачимо, команди обробки рядків в асемблері теж обробляють лише один байт або одне слово. Але командний префікс REP дозволяє використовувати ці команди для обробки рядків будь-якої довжини.

Формат команди обробки рядка:

{позначка} [[командний префікс], код команди] {[операнд1], [операнд2]}

Ланцюгова команда обробки рядка може бути закодована для виконання циклічної обробки байтів рядка за одну команду. Адреса джерела даних знаходиться у регістрі процесора SI, а приймача даних у регістрі DI. В більшості випадків регістр SI пов’язаний з сегментним регістром DS, а регістр DI з сегментним регістром ES. Нижче наведені команди обробки рядків для однобайтових та двобайтових варіантів.

Таблиця 21. Команди асемблера для обробки рядків

Команда

Операнди

Команда обробки байту

Команда обробки слова

MOVS

DI, SI

MOVSB

MOVSW

LODS

AL, SI або AX, SI

LODSB

LODSW

STOS

DI, AL або DI, AX

STOSB

STOSW

CMPS

SI, DI

CMPSB

CMPSW

SCAS

DI, AL або DI, AX

SCASB

SCASW

Операнди треба вказувати для команд типу MOVS, оскільки в них явно не вказано, з якими даними вони працюють - з байтами чи зі словами. Для команд типу MOVSB та MOVSW операнди не пишуться, оскільки по замовченню вважається, що регістри SI та DI містять відносні адреси, що вказують на необхідні комірки пам’яті. Крім того, треба ініціалізувати сегментні регістри DS та ES за допомогою директиви ASSUME. Для завантаження регістрів SI та DI використовується команда LEA. Різниця між командами MOV та LEA полягає у тому, що команда LEA завантажує вказівник на комірку пам’яті і передбачає його зміну при обробці рядка. Але формат команди LEA ідентичний формату команди MOV:

{позначка} [код команди] [операнд1], [операнд2]

Ланцюгова команда обробки рядка з префіксом REP використовує як лічильник регістр CX, тобто перед початком обробки рядка у цей регістр треба завантажувати число символів, що оброблюються. Якщо кількість байтів, що оброблюється, є непарною, то треба вибирати однобайтову команду обробки рядка, а при парної кількості байтів більш ефективним є використання двобайтних команд.

При використанні префікса REP необхідно також встановити прапор напрямку, який визначає напрямок здійснення циклічної операції:

  • для здійснення обробки символів рядка у правому напрямку, або у порядку збільшення адрес, треба за допомогою команди CLD встановити нульове значення прапора напрямку DF;

  • для здійснення обробки символів рядка у лівому напрямку, або у порядку зменшення адрес, треба за допомогою команди STD встановити одиничне значення прапора напрямку DF.

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

{позначка} [код команди]

Нижче наведений приклад, в якому команда MOVSB використовується для переміщення 20 байт із змінної S1 до змінної S2.

S1 DB 20 DUP(‘*’)

S1 DB 20 DUP(‘ ’)

..........................................

CLD

MOV CX,20

LEA DI,S1

LEA SI,S2

REP MOVSB

Використання команд CMPS та SCAS приводить також до зміни прапорів регістра стану. При цьому є можливим припинення операції порівняння при виконанні або невиконанні відповідної умови. Нижче наведені модифікації префікса REP, що дозволяють виконувати такі операції:

REPZ/REPE

повторювати ланцюгову операцію, доки прапор ZF показує «рівно або нуль». Припинення виконання ланцюгової операції, якщо ZF=0 або CX=0

REPNZ/REPNE

Повторювати ланцюгову операцію, доки прапор ZF показує «не рівно або не нуль». Припинення виконання ланцюгової операції, якщо ZF=1 або CX=0

Завдання для перевірки №3: Напишіть на мові асемблера програму, яка виконує порівняння двох рядків однакової довжини. Наприклад, порівняйте рядок «JEAN» та рядок «JOAN». Виконайте компіляцію програми та за допомогою програми AFD або TASM прослідкуйте за зміною регістра стану. Подбайте про те, щоб написана вами програма коректно працювала і при різній довжині рядків, які порівнюються.

Завдання для перевірки №4: Використовуючи написану програму, порівняйте рядок «Joan» та рядок «JOAN». Поясніть результат.

Завдання для перевірки №5: Напишіть на мові асемблера програму, яка заповнює рядок з використанням шаблонів. За допомогою цієї програми створіть рядок ‘***+++***+++***’.

Завдання для перевірки №6: Подумайте, які відомі вам опції текстових редакторів можна легко реалізувати, використовуючи асемблерні команди обробки рядків.

Завдання для перевірки №7 (ускладнене): Напишіть асемблерні програми для додавання та віднімання багаторозрядних десяткових чисел у форматі ASCII. Пам’ятайте про те, що треба враховувати прапор переносу.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]