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

M_Asm2009LS

.pdf
Скачиваний:
12
Добавлен:
23.02.2016
Размер:
2.34 Mб
Скачать

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

MOV acc,src

INC SI|ESI (або DEC SI|ESI – в залежності від напрямку просування по ланцюжку)

Дозволяються мнемоніки з вказівкою явної довжини (типу)

операндів LODSB, LODSW, LODSD.

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

Команда збереження вмісту акумулятора в ланцюжку STOS має такий загальний вигляд:

STOS dst; dst=(acc), DI|EDI=(DI|EDI)+h.

Алгоритм роботи: команда передає вміст акумулятора (байт, слово, подвійне слово) в елемент ланцюжка dst і змінює значення регістра DI|EDI так, що це значення вказує на наступний елемент ланцюжка. Цей ланцюжок повинен знаходитися в додатковому сегменті даних, початкова адреса якого визначається вмістом сегментного регістра ES і префікс заміни сегмента заборонено. З префіксом повторення команда зручна для ініціалізації ланцюжка фіксованим значенням.

Припустимі мнемоніки з явною вказівкою довжини елементів ланцюжка: STOSB, STOSW, STOSD.

Приклади розвязання задач на обробку ланцюжків

Приклад 1. Використання команди MOVS. Написати програму, яка копіює 1024 слів однієї області оперативної пам’яті в іншу.

Data

Segment para 'Data'

num = 1024

 

Sector1

dd $+4

;$ - оператор мови асемблера, який

 

 

 

; повертає поточне зміщення в сегменті.

Buf1

dw num dup('**'),'$'

Sector2

dd $+4

 

Buf2

dw num dup('++’),'$'

Data

Ends

 

Code

 

Segment

para 'code'

Assume cs:Code,ds:Data,es:Data Main proc far

push ds

91

sub ax,ax push ax mov ax,Data mov ds,ax

Call CopySector ;Виклик процедури копіювання секторів

mov ah,09h

;Вивід на екран слова OK

mov dx,offset Buf2

int 21h

 

 

retf

 

 

Main endp

 

 

CopySector proc

 

cld

; Встановити напрямок обробки рядка

 

; “вперед” (df=0).

push DS

; Зберегти вміст сегментних регістрів

;DS і ES.

push ES

les DI,Sector2; Завантаження адреси в сегментні

;та індексні регістри

lds SI,Sector1; початків областей ( ES:DI - Sector2, ; DS:SI - Sector1).

mov CX,1024;Кількість елементів, що копіюємо з

; Sector1 у Sector2.

rep movsw ; Копіювання елементів.

pop ES ; Відновлення вмісту сегментних регістрів. pop DS

ret

CopySector endp Code Ends

End Main

Приклад 2. Використання команди MOVS. Написати програму, яка циклічно зсуває на вісім байтів вправо заданий символьний рядок.

Data

Segment

para 'Data'

;..................

 

Sb

db ' Цей рядок буде зсунутий на вісім позицій вправо. $'

NumByte

dw $ - Sb

Temp

 

db 8 dup('q')

Data

Ends

 

Code

Segment para 'code'

Assume cs:Code,ds:Data,es:Data

Main proc far

92

 

push ds

 

 

 

sub ax,ax

 

 

 

push ax

 

 

 

mov ax,Data

 

 

 

mov ds,ax

 

 

 

mov AH,09h

 

;Виведення на екран стрічки Sb

 

mov DX,offset Sb

 

 

int 21h

 

 

 

Call ShiftByte

 

;Виклик процедури ShiftByte

 

mov AH,09h

 

 

 

mov DX,offset Sb

 

 

int 21h

 

 

 

retf

 

 

Main Endp

 

 

ShiftByte Proc

;Процедура зсуву.

 

std

; Встановити напрямок обробки

 

 

; рядка назад” (df=1).

 

lea SI, NumByte-2

; Адреса останнього символу рядка.

 

push DS

; Ініціалізація регістра ES.

 

pop ES

 

 

 

push SI

; Збереження індексування останнього

 

 

; символу.

 

lea DI,Temp+7; Зберігання 8 останніх символів рядка

 

mov CX,8

; у тимчасовому(допоміжному) масиві.

rep

movsb

 

 

 

pop DI

; Відновлення індексу останнього символу.

 

mov CX, NumByte

; Завантажуємо у регістр кількість

 

sub CX,9

; символів, які будемо зсувати.

rep

movsb

; Зсув символів на 8 байтів.

 

lea SI,Temp+7; Переміщення символів, які тимчасово

 

 

; зберігалися

 

mov CX,8

; у допоміжному масив,і на їх нові позиції.

rep

movsb

 

 

ret ShiftByte Endp Code Ends End Main

Приклад 3. Використання команди CMPS. Написати підпрограму, яка порівнює два символьні рядки s1 і s2 (що задаються у сегменті даних). Результат порівняння записуємо в регістр AX. Результатом

93

порівняння буде номер більшого символьного рядка (тобто 1 або 2), або значення 0, якщо вони рівні. Рядок вважається більшим, якщо його перша буква, яка не збіглася з буквою іншого рядка, має більше значення ASCII коду.

Подається тільки фрагменти сегмента коду та даних, які стосуються розв’язання задачі.

Data

Segment

para 'Data'

 

;..................

 

 

StComp1 db 'First string','$'

 

SizeComp1 = $ - StComp1-1

 

StComp2 db 'First not string','$'

 

SizeComp2 = $ - StComp2-1

 

Data

Ends

 

 

Code

Segment para 'code'

 

Assume cs:Code,ds:Data,es:Data

;...............

 

 

CmpString Proc

 

 

mov

CX,SizeComp1

; Довжина першого рядка.

 

cmp

CX,SizeComp2

; Порівняння довжин рядків.

 

jl

mst

; В регістр CX меншу довжину.

 

mov

CX,SizeComp2 ; Довжина другого рядка.

mst:

cld

 

; Встановити напрямок обробки

 

 

 

;рядка вперед” (df=0).

 

lea SI,StComp1

; Індексування рядка StComp1

 

 

 

; регістрами DS:SI.

 

push DS

; Ініціалізація регістра ES.

 

pop ES

 

 

 

lea DI, StComp2

; Індексування рядка StComp2

 

 

 

;регістрами ES:DI.

repe

cmpsb

 

; Порівняння символів, поки вони рівні.

;Аналіз виходу з циклу порівняння. Зробимо гіпотезу , що рядки рівні.

mov AX,0

; Тобто AX=0.

je mquit

; Вихід, якщо вони рівні.

mov AX,1

; Нехай перший рядок більший ( AX=1).

ja mquit

; Вихід, якщо перший рядок більший.

mov AX,2

; Другий рядок більший.

mquit: ret

 

CmpString EndP

 

Code Ends

 

End

 

94

 

Приклад 4. Використання команди SCAS. Задано масив знакових цілих чисел розмірності N. Написати процедуру, що замінює у масиві входження числа -24495 на 7000.

Data

Segment

para 'Data'

NumVec = 10

 

 

Vec

dw 0,-24495,-3,-24496,-24495,24495,0,0,-24495,9

Data

Ends

 

 

Code

Segment

para 'code'

Assume cs:Code,ds:Data,es:Data

; …

 

 

 

ScanNum Proc

near ;Процедура заміни -24495 на 7000

 

cld

 

; Встановити напрямок обробки

 

 

 

;рядка вперед” (df=0).

 

push ds

 

; Ініціалізація регістра ES.

 

pop es

 

 

 

lea di,Vec

; Адреса першого елемента вектора (ES:DI).

mov cx,NumVec

;Розмів масиву.

mov ax,-24495

;Шукане число.

m: repne scasw

 

;Сканувати масив, поки не -4495 або

 

 

 

;кінець вектора.

jne m1

 

; Якщо поточне число не -24495 , то вихід.

mov word ptr [di-2],7000 ; Поміняти -24495 на 7000.

cmp cx,0

 

;

jcxz m1

 

 

jmp m

 

; Продовжити пошук.

m1: nop

 

 

ret

 

 

ScanNum Endp

 

 

; …

 

 

 

Code

Ends

 

 

 

End Main

 

 

Приклад 5. Використання команд LODS та STOS. Написати програму кодування символьного рядка. Для кодування кожний байт циклічно зсунути на один біт вправо.

Data Segment para 'Data' NCb1 equ 90

sCb label byte nmax db NCb1 ncb db ?

Cb db NCb1 Dup (?),'$'

95

nLine

db 10,13,'$'

 

Data

Ends

 

 

Code

Segment

para 'code'

Assume cs:Code,ds:Data,es:Data

RCodeByte Proc

 

 

 

cld

 

 

; Встановити напрямок обробки рядка

 

 

 

 

;“вперед” (df=0).

 

push DS

 

; Ініціалізація регістра ES.

 

pop ES

 

 

 

lea

SI,Cb

;Завантажити в SI та DI

 

lea

DI,Cb

; адресу Cb.

 

mov CL,ncb

; CL - кількість байтів.

 

xor CH,CH

 

m15: lodsb

 

;

 

ror AL,1

;

 

stosb

 

 

 

loop m15

 

 

mov AL,'$'

 

 

stosb

 

 

 

ret

 

 

 

RCodeByte Endp

 

 

Main Proc far ;Основна процедура програми

 

push DS

 

 

 

sub AX,AX

 

 

push AX

 

 

 

mov AX,Data

 

 

mov DS,AX

 

 

lea DX,nLine

; Перехід на новий рядок

 

mov AH,09h

 

 

int 21h

 

 

 

lea DX,sCb

;Завантажити в DX адресу sCb

 

mov AH,0ah

 

 

int 21h

 

;Читання sCb

 

call RCodeByte ;Виклик процедури RcodeByte

 

lea DX,nLine

; Перехід на новий рядок

 

mov AH,09h

 

 

int 21h

 

;

 

lea DX,Cb

;Вивід на

 

mov AH,09h

 

 

int 21h

 

;екран рядка Cb

96

 

 

 

 

ret Endp

Code Ends End Main

Завдання для самостійної роботи

I.Розробити програму, яка:

1)копіює 1024 байтів з однієї області оперативної пам’яті в іншу;

2)циклічно зсунути на сім байтів вліво символьний рядок;

3)для заданого масиву беззнакових цілих чисел розмірності N, замінити у масиві входження числа - 1000 на 7000;

4)знаходить кількість входжень слова s1 в рядку s2, де в рядоку s1 заходиться слово, а рядок s2 – текстовий;

5)шифрування символьного рядка. Для шифрування кожний байт циклічно зсунути на один біт вправо.

II. Розробити програми для задач обробки символьних рядків з лабораторної роботи № 4 з використанням ланцюжкових команд.

Список літеpатуpи

1.Абель П. Язык Ассемблера для IBM PC и программирования / Пер. с англ. Ю.В. Сальникова.– М.: Высш. шк., 1992.– 447с..

2.Исида Х. Программирование для микрокомпьютеров / Пер. с яп.–

М: Мир, 1988 .– 224 с.

3.Использование Turbo Assembler при разработке программ / Сост. А.А. Чекатков. – К.: “Диалектика”, 1995. – 288 с.

4.Морс С.П., Алберт Д.Д. Архитектура микропроцессора 80286 / Пер. с англ.- М.: Радио и связь, 1990.– 304 с.

5.Григорьев В.Л. Микропроцессор і486. Архитектура и программирование ( в 4-х книгах). Книга 1. Программная архитектура. / М.: ГРАНАЛ, 1993.– 346 с.

6.Григорьев В.Л. Микропроцессор і486. Архитектура и програмирование ( в 4-х книгах). Книга 2. Аппаратная архитектура. Книга 3. Устройство с плавающей точкой. Книга 4. Справочник по системе команд / М.: ГРАНАЛ, 1993.– 382 с.

7.Юров В., Хорошенко С. Assembler: учебный курс. – СПб.: Питер Ком, 1999. – 672 с.

8.Зубков С.В. Assembler. Для DOS, Windows и Unix. – М.: ДМК, 1999. – 640 c.

9.Юров В. Assembler: учебник. – СПб.: Питер, 2001. – 624 с.

10.Юров В. Assembler: практикум. – СПб.: Питер, 2001. – 400 с.

97

11.Юров В. Assembler: специальный справочник. – СПб.: Питер, 2000. – 496с.

12.Корнеев В.В., Кисельов А.В. Современные микропроцессоры. –

М.: Нолидж, 2000. – 320 с.

98

Навчальне видання

Програмування (мова асемблера) методичні рекомендації до лабораторних робіт

Укладачі: Сопронюк Федір Олексійович (відповідальний за випуск), Лазорик Василь Васильович, Сопронюк Євген Федорович.

Літературний редактор Колодій О.В. Технічний редактор

99

Тут вы можете оставить комментарий к выбранному абзацу или сообщить об ошибке.

Оставленные комментарии видны всем.

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