Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

гос / sp-lect (1)

.pdf
Скачиваний:
19
Добавлен:
16.02.2016
Размер:
2.59 Mб
Скачать

значення або регістра ESI|RSI, або регістра EDI|RDI, або пари регістрів ESI|RSI та EDI|RDI одночасно.

Напрямок обробки залежить від значення прапорця DF регістру прапорців RFLAGS:

0, автоінкрементна адресація (обробка у бік старших адрес)

DF =

1, автодекрементна адресація (обробка у бік молодших адрес)

Команда CLD встановлює DF=0, що визначає напрямок обробки елементів ланцюжка з молодших адрес памяті в старші за рахунок автоматичного збільшення командами обробки ланцюжків значень індексних регістрів ESI|RSI та|або EDI|RDI на число, що дорівнює розміру в байтах елементів ланцюжків.

Команда STD встановлює DF=1, що визначає напрям обробки елементів ланцюжка із старших адрес памяті в молодші за рахунок автоматичного зменшення значень індексних регістрів ESI|RSI та|або EDI|RDI на , що дорівнює розміру в байтах елементів ланцюжків.

При старті додатку в середовищі 32-розрядної ОС Windows NT сегментні регістри DS та ES міститимуть однакові значення. Таким чином, завантаження селектору в сегментний регістр виконувати не потрібно, адреса ланцюжка- джерела визначається по вмісту регістру ESI, адреса ланцюжка-приймача

EDI.

В 64-розрядній ОС Windows NT сегментні регістри взагалі не використовується і завантаження селектору в сегментний регістр виконувати не потрібно, адреса ланцюжка-джерела визначається по вмісту регістру RSI, адреса ланцюжка-приймача – RDI.

3.5.1.6.2 Команди завантаження елементів з ланцюжка

LODSB

байт

 

 

 

 

Команда LODSW

копіює слово

із комірки памяті за адресою в

LODSD

подвійне слово

 

 

 

 

LODSQ

зчетверене слово

 

AL

AX збільшує, якщо DF=0

регістрах (DS:ESI)|RSI в регістр і значення

EAX зменшує, якщо DF=1

RAX

1

2

регістра ESI|RSI на не змінюючи значення регістра прапорців RFLAGS

4

8

3.5.1.6.3 Команди збереження елемента в ланцюжку

STOSB

байт

AL

 

 

 

 

 

Команда STOSW копіює слово

з регістру AX

в комірку

STOSD

подвійне слово

EAX

 

 

 

 

 

STOSQ

зчетверене слово

RAX

 

памяті за адресою

(ES:EDI)|RDI і збільшує, якщо DF=0 значення регістра

 

зменшує, якщо DF=1

 

1

2

EDI|RDI на не змінюючи значення регістра прапорців RFLAGS

4

8

3.5.1.6.4 Команди сканування ланцюжка

SCASB

AL

байта

 

 

 

 

 

Команда SCASW

вираховує з регістру AX

значення слова

в

SCASD

EAX

подвійного слова

 

 

 

 

SCASQ

RAX

зчетвереного слова

памяті за адресою в регістрах (ES:EDI)|RDI,

збільшує, якщо DF=0

значення

 

 

зменшує, якщо DF=1

 

1

2

регістра EDI|RDI на і встановлює прапорці OF, SF, ZF, AF, PF, CF

4

8

відповідно до результату операції, не зберігаючи сам результат.

3.5.1.6.5 Команди порівняння ланцюжків

CMPSB

байта

 

 

 

 

 

 

Команда CMPSW

вираховує значення слова

в комірці памяті за

CMPSD

подвійного слова

 

 

 

 

 

CMPSQ

зчетвереного слова

 

 

 

байта

 

 

 

 

 

адресою в регістрах (DS:ESI)|RSI і значення

слова

в комірці

 

 

подвійного слова

 

 

 

 

 

 

 

зчетвереного слова

 

памяті за адресою в регістрах (ES:EDI)|RDI,

збільшує, якщо DF=0

значення

 

 

зменшує, якщо DF=1

 

1

2

регістрів ESI|RSI та EDI|RDI на і встановлює прапорці відповідно до

4

8

результату операції, не зберігаючи сам результат.

3.5.1.6.6 Команди пересилання ланцюжків

MOVSB

байта

 

 

 

 

Команда MOVSW

копіює значення слова

із комірки памяті за

MOVSD

подвійного слова

 

 

 

 

MOVSQ

зчетвереного слова

 

адресою в регістрах (DS:ESI)|RSI в комірку памяті за адресою в (ES:EDI)|RDI і

1

збільшує, якщо DF=0 2

значення регістрів ESI|RSI та EDI|RDI на

зменшує, якщо DF=1 4

8

3.5.1.6.7 Префікси повторення

Автоматична зміна вмісту регістрів ESI|RSI та|або EDI|RDI абсолютно всіма командами обробки ланцюжків робить їх зручними для використання в циклах, для чого, власне, це й передбачалося. Наприклад, пошук в ланцюжку певного значення без використання і з використання команд обробки ланцюжків може виконуватися наступним чином:

mov ecx,<довжина ланцюжка>

mov ecx,<довжина ланцюжка>

lea edi,<приймач>

lea edi,<приймач>

mov al,<значення для пошуку>

mov al,<значення для пошуку>

@@: cmp al,byte ptr [edi]

@@: scasb

jz @F

loopne @B

inc edi

@@: ………………………….

loop @B

 

@@: ………………………….

 

Як видно з прикладу, використання автоінкрементної/автодекрементної адресації, властивої командам обробки ланцюжків, зменшує кількість використаних команд. Ще більше скорочення коду дає використання команд обробки ланцюжків, обидва операнда яких можуть розташовуватися у памяті. Наприклад, пересилання з одного ланцюжка байтів в інший без використання і з використанням команд обробки ланцюжків може виконуватися наступним чином:

mov ecx,<довжина ланцюжка>

mov ecx,<довжина ланцюжка>

lea esi,<джерело>

 

lea esi,<джерело>

lea edi,<приймач>

 

lea edi,<приймач>

@@: mov al, byte ptr [esi]

@@:

movsb

mov byte ptr [edi],al

 

loop @B

inc esi

inc edi

loop @B

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

Префікс REP примушує командну обробки ланцюжків повторюватися поки RСХ|ЕСХ не рівний нулю (RСХ|ЕСХ раз).

Префікс REPE|REPZ примушує командну обробки ланцюгів повторюватися поки RСХ|ЕСХ не рівний нулю і прапорець нуля встановлений

(ZF=1).

Префікс REPNE|REPNZ примушує командну обробки ланцюгів повторюватися поки RСХ|ЕСХ не рівний нулю і прапорець нуля скинуто

(ZF=0).

З використанням префіксів повторення попередні приклади будуть

виглядати наступним чином:

 

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

; Пошук в ланцюжку

mov ecx,<довжина ланцюжка>

mov ecx,<довжина ланцюжка>

lea esi,<джерело>

lea edi,<приймач>

lea edi,<приймач>

mov al,<значення для пошуку>

rep movsb

repne scasb

4 ОБРОБКА СТРУКТУРОВАНИХ ТИПІВ ДАНИХ

4.1 Одновимірні масиви

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

SIZE змінна
SIZEOF змінна|тип
LENGTH змінна
LENGTHOF змінна
TYPE вираз

Для роботи з масивами зокрема, а в загальному випадку з будь якими структурованими даними, зручно використовувати оператори MASM, які описані у наступній таблиці.

Таблиця 6.1 – Оператори MASM для роботи з типами даних

Оператор Опис

Повертає число байтів у змінній, що було виділено при її початковій ініціалізації.

Повертає число байтів, що займає змінна або тип.

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

Повертає число обєктів даних у змінній.

Повертає тип (розмір у байтах) виразу.

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

Приклад 4.1 Визначення суми позитивних елементів у масиві байт, і кількість негативних елементів у масиві слів.

.386

.model flat, stdcall option casemap :none

.data

xdb 1,2,3,-4,-5,6,0,7,8,0,5,8

y

dw 1,2,3,-4,-5,6,0,7,8,0,5,0

.code

 

start: lea esi,x xor ebx,ebx

mov ecx, lengthof x m1: cmp byte ptr [esi],0

jle m2

add bl, byte ptr [esi] adc bh,0

m2: inc esi loop m1 xor edi,edi lea esi,y

mov ecx,lengthof y m3: cmp word ptr [esi],0

jge m4 inc edi

m4: add esi, type y loop m3

ret end start

Приклад 4.2 Визначення суми позитивних елементів з парними індексами одновимірного масиву слів.

В загальному випадку, при довільному місце розташуванні масиву в памяті адреси його елементів можуть бути як парними, так і не парними числами, що будуть зростати для масиву слів з кроком 2. Отже парність чи не парність індексу елементу масиву не можна визначати перевіривши парність чи не парність його адреси.

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

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

масиву, а в масиві з чотирьох елементів вже два мають парні індекси і такий стрибок треба виконувати.

В наведеному нижче прикладі обрано інший метод адресації елементів масиву базову індексну адресацію з масштабуванням. По перше, в такому випадку кількість повторень циклу фіксована і визначається тільки кількістю елементів масиву незалежно від того парна вона чи не парна, а по-друге, така адресація дозволяє оперувати не адресами, а логічними індексами 0,1,2,...

елементів масиву, що відповідає нашим інтуїтивним уявленням і використовується мовами програмування високого рівня. Недоліком такого підходу у порівнянні із методом «перестрибування» не потрібних елементів є збільшення кількості виконуваних команд.

Суть базової індексної адресації можна сформулювати словосполученням «зміщення від зміщення». Завантаження в базовий регістр адреси початку масиву схоже на перенесення центру координат в нову вихідну точку. Після цього незалежно від того де розміщується масив в сегменті даних, його елементи адресуються зі зміщення 0 відносно нової точки відліку. Для завдання зміщення «в нових координатах» використовується індексний регістр, який для узгодженості з розміром даних множиться на розмір елементу масиву в байтах (2 для слова). При цьому значення індексного регістру (недарма ж він зветься індексним) збільшується в циклі в природному для індексів елементів масиву порядку 0,1,2,3,..., що і дозволяє звертатися до елементів масиву за їх номерами, незалежно від того, які адреси памяті насправді їм відповідають.

.386

.model flat, stdcall

option casemap :none

.data

x dw 1,2,3,-4,-5,6,0,7,8,0,5,8,3

.code

start:

lea ebx,x

xor eax,eax

xor edx,edx xor esi,esi

mov ecx,lengthof x next: test esi,1

jnz @F

cmp word ptr [ebx+esi*2],0 jle @F

add ax, word ptr [ebx+esi*2] adc dx,0

@@: inc esi loop next push dx push ax pop ebx ret

end start

Приклад 4.3 Визначення максимального елементу у масиві слів (значення та індексу).

.386

.model flat, stdcall option casemap :none

.data

x dw 7,8,0,5,8,3,-10,5,0,0,14,-5,3,-7

.code

start: lea ebx,x xor esi,esi mov ax,[ebx] mov edi,esi

mov ecx, lengthof x dec ecx

inc esi

next: cmp [ebx+esi*2],ax jle @F

mov ax,[ebx+esi*2]

mov edi,esi

@@: inc esi

loop next

ret end start

Цей приклад дозволить нам також продемонструвати використання групи команд CMOVcc, яку ми пропустили при розгляді команд пересилання.

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

В подальшому для зменшення розгалуджень в програмах при вирішенні деяких типових задач програмування в систему команд було введено групу команд умовного пересилання. Узагальнене мнемоничне позначення команд цієї групи CMOVcc r, r/m. Вони дозволяють виконати завантаження у регістр значення з памяті або іншого регістру при виконанні умови, узагальнене мнемонічне позначення якої «сс» співпадає з використовуваним при описі команд умовної передачі керування. Самі команди не впливають на стан RFLAGS і тому припустимо використання декількох команд CMOVcc одна за одною.

 

Приклад 4.4 Визначення значення та індексу максимального елементу у

масиві слів з використанням команд умовного пересилання.

.686

; для CMOVcc

.model flat, stdcall

option casemap:none

.data

x dw 7,8,0,5,8,3,-10,5,0,0,14,-5,3,-7

.code

start: lea ebx,x

Соседние файлы в папке гос