Все про Assembler українською мовою на сайті net.kr.ua

 

:: Меню ::

Головна
Введення
Архітектура реального режиму
Основи програмування
Команди і алгоритми
Розширені можливості сучасних мікропроцесорів
Система команд процесорів Intel
Книга для гостей
Контакти
Добавити у вибране

:: Друзі ::

  В нашей компании Проститутки Нижневартовска недорого, со скидками.   По привлекательной цене купить мужские кроссовки недорого со скидками, в любое время.
 

:: Лічильники ::

=

 

 

 

 

fff00e50

Обробка рядків

Для роботи з рядками, або ланцюжками символів або чисел (тобто просто кажучи, з масивами довільних даних) в МП передбачений ряд спеціальних команд:

movs - пересилка рядка;
cmps - порівняння двох рядків;
seas - пошук в рядку заданого елементу;
lods - завантаження акумулятора (регістрів AL або АХ) з рядка;
stos - запис елементу рядка з акумулятора (регістрів АХ або AL).

Ці команди дуже зручні, проте їх використання зв'язане з деякими труднощами, оскільки процесор, виконуючи ці команди, неявним чином використовує ряд своїх регістрів. Тільки якщо всі ці регістри настроєні належним чином, команди виконуватимуться правильно. В результаті включення в програму пропозиції з командою, наприклад, movs, вимагає інший раз 6-7 додаткових пропозицій, в яких здійснюється підготовка умов для правильного виконання цієї команди.
Хоча команди обробки рядків, як правило, включаються в програму без явної вказівки операндів, проте кожна команда, насправді, використовує два операнди. Для команд seas і stos операндом-джерелом служить акумулятор, а операнд-приймач знаходиться в пам'яті. Для команди lods, навпаки, операнд-джерело знаходиться в пам'яті, а приймачем служить акумулятор. Нарешті, для команд movs і cmps обидва операнди, і джерело, і приймач, знаходяться в пам'яті.
Всі дані команди, виконуючи різні дії, підкоряються однаковим правилам, перерахованим нижче. Операнди, що знаходяться в пам'яті, завжди адресуються одноманітно: операнд-джерело через регістри Ds:si, а операнд-приймач через регістри Es:di. При одноразовому виконанні команди обробляють тільки один елемент, а для обробки рядка команди повинні передувати одним з префіксів повторення. В процесі обробки рядка регістри SI і DI автоматично зміщуються по рядку вперед (якщо прапор DF = 0) або назад (якщо прапор DF = 1), забезпечуючи адресацію подальших елементів. Кожна команда має модифікації для роботи з байтами або словами (наприклад, movsb і movsw).
Таким чином, для правильного виконання команд обробки рядків необхідно (у загальному випадку) заздалегідь набудувати регістри Ds:si і Es:di, встановити або скинути прапор DF, занести в СХ довжину оброблюваного рядка, а для команд seas і stos ще помістити операнд-джерело в регістр АХ (або AL при роботі з байтами).
Проте сама операція, після всього цього налаштування, здійснюється однією командою, яка зазвичай навіть не містить операндів, хоча може мати префікс повторення.
Варто підкреслити, що рядки, що обробляються даними командами, можуть знаходитися в будь-якому місці пам'яті: у полях даних програми, в системних областях даних, в ПЗП, у відеобуфері. Наприклад, за допомогою команди movs можна скопіювати масив даних з однієї масивної змінної в іншу, а можна переслати сторінку тексту на екран терміналу. Розглянемо декілька прикладів використання команд обробки рядків, обмежившись лише тими фрагментами програм, які мають відношення до даного питання.

Приклад 3-6. Читання з ПЗУ BIOS дати його випуску

;У програмному сегменті

main proc

mov Ax,0f000h    ;Занесем у DS

mov Ds,ax            ;Сегментный адреса ПЗП BIOS

mov Si,0fff5h      ;Смещение до того, що цікавить нас полю

mov Ax,data          ;Настроим RS

mov Rs,ax            ;на сегмент даних програми

mov Di,offset bios ;Смещение до поля для зберігання дати

mov Cx,8               ;Перенести 8 байт

cld                           ;Движение по рядку вперед

rep movsb              ;Перенос байтів

;Виведемо отриману інформацію на екран

mov Ax,data         ; Тепер набудуємо DS

mov Ds,ax           ;на сегмент даних програми

mov  Ah,40h         ;Функция виводу

mov Bx,1              ;Дескриптор екрану

mov Cx,8              ;Вывести 0 байт

mov Dx,offset bios  ;Смещение у рядку

int 21h                      ; Виклик DOS

;У сегменті даних

bios db 8 dup (')      ;Поле для зберігання дати

Відомо, що в ПЗП BIOS, сегментна адреса якого складає F000h (див. мал. 1.5), разом з програмами управління апаратурою комп'ютера, зберігаються ще і деякі ідентифікатори. Так, у восьми байтах ПЗП, починаючи з адреси F000h:fffsh, записана в кодах ASCII дата розробки ПЗП. У прикладі 3.6 виконується читання цієї дати, збереження її в пам'яті і вивід на екран для контролю. Оскільки дата, що цікавить нас, зберігається в ПЗУ BIOS в кодах ASCII, ніяких перетворень вмісту цієї ділянки ПЗП перед виводом на екран не потрібні.
У програмі здійснюється налаштування всіх необхідних для виконання команди movs регістрів (Ds:si, Es:di, CX і прапора DF) і однією командою movsb з префіксом rep вміст необхідної ділянки ПЗП переноситься в полі bios. Перенесення рядка байтами підкреслює її формат (у рядку записані байтові коди ASCII), проте в нашому прикладі, при парному числі переносимих байтів, ефективніше здійснити перенос по словах. У цьому варіанті команда movs фактично повторюватиметься не 8 разів, а тільки 4. Для цього досить занести в СХ число 4 (замість 8) і використовувати варіант команди niovsw.
Для виконання команди movs нам довелося набудувати сегментний регістр DS на сегмент BIOS. Якщо надалі передбачається звернення до полів даних програми, як це має місце в прикладі 3-6, в регістр DS слід занести сегментну адресу сегменту даних. Після цього, набудувавши решту регістрів для виклику функції 40h, прочитану з BIOS рядок можна вивести на екран.
У розглянутому прикладі неявно передбачалося, що програма буде надалі якось використовувати отриману з BIOS інформацію. Якщо завдання програми полягає просто у виводі на екран дати випуску BIOS, то немає необхідності спочатку копіювати цю дату з BIOS в поля даних програми, а потім виводити її на екран. Можна було поступити набагато простіше: набудувавши регістр DS на сегмент BIOS, а регістр DX на адресу рядка з датою, викликати функцію 40h і вивести на екран текст безпосередньо з сегменту BIOS. Тоді змістовна частина програми скоротиться в два рази і набере такого вигляду:

mov Ax,0f00h       ;Настроим DS

mov Ds,ax            ;на сегмент BIOS

mov Ah,40h           ;Функция виводу

mov Bx,1               ;Дескриптор екрану

mov Cx,8               ;Вывести 8 байт

mov Dx,0fffsh    ;Смещение до дати

int 21h                     ;Вызов DOS

Приведений фрагмент не має відношення до даного розділу, оскільки в нім вже немає команд обробки рядків. В той же час він підкреслює важливість сегментних регістрів і гнучкість сегментної адресації. Функція 40h чекає знайти адресу рядка, що виводиться на екран, в регістрах Ds:dx, і ніякі інші регістри в цьому випадку використовувати не можна. З іншого боку, ці регістри можна набудувати на будь-яку ділянку пам'яті і вивести на екран (а також і на принтер, у файл або в послідовний порт) дані звідки завгодно.
Розглянемо тепер приклад роботи з командами lods і stos, які можна використовувати як окремо, так і в парі один з одним. Ці команди дуже зручні, зокрема, для прямого звернення до відеопам'яті.
До екрану, як і до будь-якого іншого пристрою, що входить до складу комп'ютера, можна звертатися трьома способами: за допомогою функцій DOS (переривання 21h), з використанням переривання BIOS (для управління екраном використовується переривання 10h) і, нарешті, шляхом прямого програмування апаратури, в даному випадку відеобуфера (відеопам'яті). Функції DOS дозволяють виводити тільки чорно-білий текст і мають ряд інших обмежень (не можна очистити екран, немає засобів позиціонування курсора); при використанні переривання BIOS всі ці обмеження знімаються, проте програмування за допомогою засобів BIOS вельми трудомістко; нарешті, прямий запис у відеопам'ять, надаючи можливість виведення кольорового тексту в будь-яку точку екрану, є процедурою дуже простій і, до того ж, підвищує швидкість виводу (по порівнянням з використанням системних засобів) в десятки і сотні разів. Пряме звернення до відеобуфера зручно використовувати, наприклад, в обробниках переривань, де заборонений виклик функцій DOS і є обмеження на звернення до засобів BIOS.
Хай по ходу програми необхідно вивести в нижній рядок екрану застережливе повідомлення. Для цього в програму треба включити наступні пропозиції:

Приклад 3-7. Вивід на екран прямим записом у відеопам'ять

;У полях даних, що адресуються через DS

msg db 'Вимірювання закінчені'

msg_len=$-msg              ;Длина рядки

  ;У програмному сегменті

mov Si,offset msg            ;DS:31->выводимая рядок

mov Ax,ob800h               ;Сегментный адреса відеобуфера

mov Es,ax                      ;Будем адресувати через ES

mov Di,25*80*2              ;Смещение до останнього рядка екрану

mov Cx,msg_len              ;Счетчик циклу виведення символів

eld                                 ;DF= 0, рух по рядку

                                     ; і по екрану вперед

mov Ah,31h                    ;Атрибут символов-синій по

                                    ; блакитному

outher: lodsb                  ;Взять символ з рядка в AL

show                              ; Вивід на екран символу

                                      ; з AL і його атрибуту з AH

loop outser                      ; Цикл

Регістри Ds:si настроюються на адресу почата рядка, що виводиться; регістри Es:di - на адресу необхідної позиції у відеобуфері. У регістр СХ треба помістити довжину рядка в байтах, а прапор DF скинути, щоб рухатися по рядку вперед. На екран виводитиметься вміст регістра АХ, в молодшому байті якого повинен знаходитися код ASCII символу, що виводиться, а в старшому байті - атрибут символу, тобто код кольору символу (у молодшому півбайті) і код кольору фону (у старшому півбайті). У прикладі число 31h утворює сині символи по бірюзовому фону. За бажання можна вибрати іншу комбінацію квітів, вибравши її за допомогою таблиці. 3.1.

Таблиця 3.1. Коди квітів стандартної колірної палітри                                                                                                                                            

Код  Колір    Код   Колір
0h  Чорний     8h        Сірий
1h   Синій   9h  Блакитний
2h   Зелений  10h   Салатовий
3h   Бірюзовий    11h Ясно-бірюзовий
4h  Червоний     12h    Рожевий
5h  Фіолетовий  13h   Ясно-фіолетовий
6h  Коричневий 14h   Жовтий
7h     Білий   15h    Яскраво-білий

Вибираючи кольори, слід мати на увазі, що при стандартному налаштуванні відеосистеми для кольору фону можна використовувати лише значення з лівого стовпця таблиці; вибір будь-якого яскравого кольору з правого стовпця приведе у виведенню мерехтливого символу. Наприклад, атрибут символу Bill утворює синій мерехтливий символ на бірюзовому фоні (а не синій символ на ясно-бірюзовому фоні).
Змістовну частину циклу виводу утворюють дві команди lodsb і stosw. Перша команда завантажує в регістр AL код чергового символу, друга виводить його разом з атрибутом, що зберігається в АН, на екран. При цьому після кожного виконання команди lodsb вміст SI збільшується процесором на 1, зміщуючи адресацію до наступного символу рядка; в той же час кожне виконання команди stosw збільшує DI на 2 (тому що команда stosw працює із словами), зміщуючи адресацію на екрані на 2 байт, тобто якраз до позиції наступного символу.
Приклади використання команд cmps і seas можна знайти в Додатку.

-

:: Наша кнопка ::

Отримати код:

Підтримайте наш сайт і розмістіть нашу кнопку на своєму ресурсі.


:: Популярне ::

-


:: Посилання ::

-


 

 

 


Copyright © net.kr.ua, 2019-2025 (assem.us)