Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lekz._13.doc
Скачиваний:
2
Добавлен:
11.08.2019
Размер:
256.51 Кб
Скачать

Системне програмування, доц. І.І. Мітасов, 2010р. Лекція 13, 12 сторінок

Тема 2. Архітектура процесора і мова асемблера: Основи програмування на мові асемблера

ЛЕКЦІЯ 13. Ланцюжкові команди

Питання лекції:

  • операції-примітиви, префікси повторення;

  • операції пересилання, порівняння і сканування ланцюжків;

  • завантаження елементу ланцюжка в акумулятор;

  • перенесення елементу з акумулятора в ланцюжок;

  • введення-виведення елементу ланцюжка з порту / в порт вводу-виводу.

Ці команди також називають командами обробки рядків символів. Відмінність в тому, що під рядком символів тут розуміється послідовність байтів, а ланцюжок - це більш загальна назва для випадків, коли елементи послідовності мають розмір більше байту - слово або подвійне слово. Таким чином, ланцюжкові команди дозволяють проводити дії над блоками пам'яті, що представляють собою послідовності елементів наступного розміру:

● 8 біт - байт; ● 16 біт - слово; ● 32 біта - подвійне слово.

Вміст цих блоків для мікропроцесора не має ніякого значення. Це можуть бути символи, числа і все що завгодно. Головне, щоб розмірність елементів збігалася з однією з перерахованих і ці елементи знаходилися в сусідніх комірках пам'яті.

1. Операції-примітиви, префікси повторення

Всього в системі команд мікропроцесора є сім операцій-примітивів обробки ланцюжків. Кожна з них реалізується в мікропроцесорі трьома командами, у свою чергу, кожна з цих команд працює з відповідним розміром елемента - байтом, словом або подвійним словом. Особливість всіх ланцюжкових команд в тому, що вони, крім обробки поточного елемента ланцюжка, здійснюють ще й автоматичне просування до наступного елемента даних ланцюжка. У таблиці 13.1 перераховані операції-примітиви і команди, за допомогою яких вони реалізуються.

Л

rep repe або repz

repne або repnz

огічно до цих команд віднести і так звані префікси повторення. Згадайте формат машинної команди і його перший необов'язковий байт префіксів. Один з можливих типів префіксів - це префікси повторення. Вони призначені для використання ланцюжковими командами.

Префікси повторення мають свої мнемонічні позначення:

Ці префікси повторення вказуються перед потрібної ланцюжковою командою в полі мітки. Ланцюжкова команда без префікса виконується один раз. Розміщення префікса перед ланцюжковою командою змушує її виконуватися в циклі.

Відмінності наведених префіксів в тому, на якій підставі приймається рішення про циклічне виконання ланцюжкової команди: станом регістра ecx/cx або по прапору нуля zf:

  • префікс повторення rep (REPeat). Цей префікс використовується з командами, що реалізують операції-примітиви пересилання і збереження елементів ланцюжків - відповідно, movs і stos. Префікс rep змушує дані команди виконуватися, поки вміст у ecx/cx не стане рівним 0. При цьому ланцюжкова команда, перед якою стоїть префікс, автоматично зменшує вміст ecx/cx на одиницю. Та ж команда, але без префікса, цього не робить;

  • префікси повторення repe або repz (REPeat while Equal or Zero). Ці префікси є абсолютними синонімами. Вони змушують ланцюжкову команду виконуватися до тих пір, поки вміст ecx/cx не дорівнює нулю або прапор zf дорівнює 1. Тільки-но одна з цих умов порушується, керування передається наступній команді програми. Завдяки можливості аналізу прапора zf, найбільш ефективно ці префікси можна використовувати з командами cmps і scas для пошуку відрізняються елементів ланцюжків;

  • префікси повторення repne або repnz (REPeat while Not Equal or Zero). Ці префікси також є абсолютними синонімами. Їхня дія на ланцюжкову команду дещо відрізняється від дій префіксів repe/repz. Префікси repne/repnz змушують ланцюжкову команду циклічно виконуватися до тих пір, поки вміст ecx/cx не дорівнює нулю або прапор zf дорівнює нулю. При невиконанні одного з цих умов робота команди припиняється.

Дані префікси також можна використовувати з командами cmps і scas, але для пошуку співпадаючих елементів ланцюжків.

Таблиця 13.1 – Операції-примітиви і команди обробки ланцюжків

Операції -примітиви

Команди

Пересилання ланцюжка

movs адреса_приймача,адреса_джерела movsb movsw movsd

Порівняння ланцюжків

cmps адреса_приймача,адреса_джерела cmpsb cmpsw cmpsd

Сканування ланцюжка

scas адреса_приймача scasb scasw scasd

Загрузка елемента з ланцюжка

lods адреса_джерела lodsb lodsw lodsd

Збереження елемента в ланцюжку

stos адреса_приймача stosb stosw stosd

Отримання еле - ментів ланцюжка з порту вводу-виводу

ins адреса_приймача,номер_порта insb insw insd

Вивід елементів ланцюжка в порт вводу-виводу

outs номер_порта,адреса_джерела

outsb outsw outsd

Наступний важливий момент, пов'язаний з ланцюжковими командами, полягає в особливостях формування фізичної адреси операндів адреса_джерела і адреса_ пріймача.

Ланцюжок-джерело, що адресується операндом адреса_джерела, може знаходитися в поточному сегменті даних, котрий визначається регістром ds. Ланцюжок-приймач, що адресується операндом адреса_пріймача, повинен бути в додатковому сегменті даних, що адресується сегментним регістром es.

Важливо відзначити, що допускається заміна (за допомогою префікса заміни сегмента) тільки регістра ds, регістр es підміняти не можна.

Другі частини адрес - зміщення ланцюжків - також знаходяться в певних місцях. Для ланцюжка-джерела це регістр esi/si (Source Index register - індексний регістр джерела). Для ланцюжка-одержувача це регістр edi/di (Destination Index register - індексний регістр приймача). Таким чином, повні фізичні адреси для операндів ланцюжкових команд наступні:

● адреса_джерела - пара ds:esi/si; ● адреса_пріймача – пара es:edi/di.

Зверніть увагу на те, що всі сім груп команд, що реалізують ланцюжкові операції-примітиви, мають схожий за структурою набір команд. У кожному з цих наборів присутня одна команда з явною вказівкою операндів і три команди, які не мають операндів.

Насправді, набір команд мікропроцесора має відповідні машинні команди тільки для ланцюжкових команд асемблера без операндів. Команди з операндами використовуються транслятором асемблера тільки для визначення типів операндів.

Після того як з'ясовано тип елементів ланцюжків по їх опису в пам'яті, генерується одна з трьох машинних команд для кожної з ланцюжкових операцій. З цієї причини всі регістри, що містять адреси ланцюжків, мають бути ініціалізованими заздалегідь, у тому числі і для команд, що допускають явну вказівку операндів. У силу того, що ланцюжки адресуються однозначно, немає особливого сенсу застосовувати команди з операндами. Головне, що ви повинні запам'ятати, - правильне завантаження регістрів покажчиками обов'язково потрібне до видачі будь-якої ланцюжкової команди.

Останній важливий момент, що стосується всіх ланцюжкових команд, - це напрямок обробки ланцюжків. Є дві можливості:

• від початку ланцюжка до його кінця, тобто в напрямку зростання адрес;

• від кінця ланцюжка до початку, тобто в напрямку зменшення адрес.

Як ми побачимо нижче, ланцюжкові команди самі виконують модифікацію регістрів, що адресують операнди, забезпечуючи тим самим автоматичне просування по ланцюжку. Кількість байт, на які ця модифікація здійснюється, визначається кодом команди. А ось знак цієї модифікації визначається значенням прапора напрямку df (Direction Flag) в регістрі eflags/flags:

• якщо df = 0, то значення індексних регістрів esi/si і edi/di буде автоматично збільшуватися (операція інкремента) ланцюжковими командами, тобто обробка буде здійснюватися в напрямку зростання адрес;

• якщо df = 1, то значення індексних регістрів esi/si і edi/di буде автоматично зменшуватися (операція декремент) ланцюжковими командами, тобто обробка буде йти в напрямку зменшення адрес.

Станом прапора df можна керувати за допомогою двох команд, які не мають операндів: cld (Clear Direction Flag) - очистити прапор напрямку. Команда скидає прапор напрямку df в 0. std (Set Direction Flag) - встановити прапор напрямку. Команда встановлює прапор напрямку df в 1.

Це вся інформація, що стосується загальних властивостей ланцюжкових команд. Далі ми більш детально розглянемо кожну операцію-примітив і команди, які її реалізують. При цьому більш детально ми будемо розглядати одну команду в кожній групі ланцюжкових команд - команду з операндами. Це буде робитися з тих міркувань, що це більш загальна команда в сенсі обмежень, що накладаються на типи операндів.

2. Операція пересилання ланцюжків

Команди, що реалізують цю операцію-примітив, копіюють елементи з однієї області пам'яті (ланцюжка) в іншу. Розмір елемента визначається застосовуваною командою. Система команд TASM надає програмісту чотири команди, які працюють з різними розмірами елементів ланцюжка:

movs адреса_приймача, адреса_джерела (MOVe String) - переслати ланцюжок;

movsb (MOVe String Byte) - переслати ланцюжок байтів;

movsw (MOVe String Word) - переслати ланцюжок слів;

m

movs адреса_приймача,адреса_джерела

ovsd (MOVe String Double word) – пересл. ланцюжок подвійних слів.

Команда movs:

Команда копіює байт, слово або подвійне слово з ланцюжка, що адресується операндом адреса_джерела, в ланцюжок, що адресуються операндом адреса_приймача. Розмір елементів, що пересилаються, асемблер визначає, виходячи з атрибутів ідентифікаторів, що вказують на області пам'яті приймача і джерела. Приміром, якщо ці ідентифікатори були визначені директивою db, то пересилатися будуть байти, якщо ідентифікатори були визначені за допомогою директиви dd, то пересиланню підлягають 32-бітові елементи, тобто подвійні слова.

Раніше вже було зазначено, що для ланцюжкових команд з операндами, до яких належить і команда пересилання movs адреса_приймача, адреса_джерела, не існує машинного аналога. Під час трансляції в залежності від типу операндів транслятор перетворює її на одну з трьох машинних команд: movsb, movsw або movsd.

Сама по собі команда movs пересилає тільки один елемент, виходячи з його типу, і модифікує значення регістрів esi/si і edi/di. Якщо перед командою написати префікс rep, то однією командою можна переслати до 64 Кбайт даних (якщо розмір адреса в сегменті 16 біт - use16) або до 4 Гбайт даних (якщо розмір адреси в сегменті 32 біт - use32).Число пересилаються елементів повинно бути додано в лічильник - регістр cx (use16) або ecx (use32).

Перерахуємо набір дій, які потрібно виконати в програмі для того, щоб переслати послідовності елементів з однієї області пам'яті в іншу за допомогою команди movs. В загальному випадку цей набір дій можна розглядати як типовий для виконання будь-якої ланцюжкової команди:

• встановити значення прапора df в залежності від того, в якому напрямку будуть оброблятися елементи ланцюжка - у напрямку зростання або зменшення адрес;

• завантажити покажчики на адреси ланцюжків у пам'яті в пари регістрів ds:(e)si і es:(e)di;

• завантажити в регістр ecx/cx кількість елементів, що підлягають обробці;

• видати команду movs з префіксом rep.

На прикладі лістингу 1 розглянемо, як ці дії реалізуються програмно. У цій програмі здійснюється пересилання символів з одного рядка в інший. Рядки знаходяться в одному сегменті пам'яті. Для пересилання використовується команда-примітив movs з префіксом повторення rep.

Лістинг 1 Пересилання рядків командою movs

;prg_13_1.asm

MASM

MODEL small

STACK 256

.data

source db 'Тестуємий рядок','$' ; рядок-джерело

dest db 19 DUP (' ') ; рядок-приймач

.code

assume ds:@data,es:@data

main: ;точка входу в програму

mov ax,@data ;завантаження сегментних регістрів

mov ds,ax ;налаштування регистрів DS і ES

mov es,ax ;на адресу сегмента даних

cld ; скидання прапора DF - обробка рядка від початку до кінця

lea si,source ; завантаження в si зміщення рядка-джерела

lea di,dest ; завантаження в DS зміщення рядка-приймача

mov cx,20 ; для префікса rep - лічильник повторень (довжина рядка)

rep movs dest,source ; пересилання рядка

lea dx,dest

mov ah,09h ; виведення на екран рядка-приймача

int 21h

exit:

mov ax,4c00h

int 21h

end main

3. Операція порівняння ланцюжків

Команди, що реалізують цю операцію-примітив, порівнюють елементи ланцюжка-джерела з елементами ланцюжка-приймача. Тут ситуація з набором команд і методами роботи з ними аналогічна операції-примітиву пересилання ланцюжків. TASM надає програмісту чотири команди порівняння ланцюжків, що працюють з різними розмірами елементів ланцюжка:

cmps адреса_приймача, адреса_джрела (CoMPare String) - порівняти рядки;

cmpsb (CoMPare String Byte) - порівняти рядок байт;

cmpsw (CoMPare String Word) - порівняти рядок слів;

cmpsd (CoMPare String Double word) - порівняти рядок подвійних слів.

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