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

M_Asm2009LS

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

 

add

DL,'0'

;5) Перетворення остачі в ASCII

 

 

 

; символ

 

mov

outdecimal[SI],DL ; 6) Запис символу в буфер

 

dec

SI

;6 )Підготовка для обробки

 

 

 

; наступного символу

 

cmp

AX,0

; 7)

 

jnz

n1

;7)

 

mov

DL,sign

;8)

 

cmp

DL,1

;8)

 

jne

n2

 

 

mov

outdecimal[SI],’–‘ ;8)

n2:

mov

AH,9

;

 

lea

DX,outdecimal

 

 

int

21h

 

 

pop

BX

 

 

pop

CX

 

 

pop

DX

 

 

pop

SI

 

 

ret

 

 

outinteger endp

 

 

Code

Ends

 

 

 

End Main

 

 

Розвязування задач за тематикою заняття

Задача 1. Розробити програму обчислення виразу:

 

 

f=a*b-c-d%a+c/b+(a*d)/c,

де

a = 21,

b = -30, c = 478, d =1347.

Розв’язання.

 

Data

Segment

para 'Data'

 

a db 21

 

 

b db -30

 

 

c dw 478

 

 

d dw 1347

 

 

f dw 0

 

 

Data

Ends

 

 

Code

Segment para 'Code'

 

Assume cs:Code,ds:Data

 

Main

Proc far

 

push DS

 

 

81

sub AX,AX

 

 

push AX

 

 

mov AX,Data

 

 

mov DS,AX

 

 

mov ES,AX

 

 

mov AL,A

; Завантажити А в регістр AL.

imul b

;(AL)*B -> (AX) .

sub AX,C

; AX-C -> AX.

mov word ptr f,AX ; Зберегти AX в F. F=A*B-C.

mov AL,a

; Завантажити А в регістр AL. F=F-D % A .

cmp AL,0

; Чи в AL не 0, щоб не ділити на 0.

je ErorrExit

; Якщо AL=0, то вхід із програми.

cbw

; Розширити вміст AL до слова AX.

mov BX,AX

; AX -> BX.

mov AX,word ptr d;

AX <- D.

cwd

;

Розширити вміст AX до подвійного слова.

idiv BX

; (DX,AX)/BX -> результат у AX, остачу в DX.

sub word ptr f,DX

; F=F-остача від ділення D/A

jo ErorrExit

; Якщо переповнення, то вхід з програми.

mov AL,b

; F=F+C/B.

cmp AL,0

; Чи в AL не 0, щоб не ділити на 0.

je ErorrExit

; Якщо AL=0 вихід з програми.

cbw

; Розширити вміст AL до слова AX.

mov BX,AX

; AX -> BX.

mov AX,c

; AX= C

cwd

; Розширити вміст AX до подвійного слова.

idiv BX

;(DX,AX)/BX -> результат у AX.

add word ptr f,AX

 

 

jo ErorrExit

; Якщо переповнення, то вихід з програми.

mov AL,a

; F=F+(A*D)/C.

cbw

; AL <- A, AL -> AX.

imul word ptr d ; (AX)*D -> (DX,AX).

cmp DX,c

; C ? ( DX).

jg ErorrExit

; Якщо C<(DX), то переповнення і вхід

 

; із програми.

idiv c

; (DX,AX)/BX -> результат у AX.

add word ptr f,AX ; F=F+(A*D)/C. ErorrExit: nop

ret Endp

82

Code Ends

End Main

Задача 2. Задана послідовність цілих чисел{ai }in=1 . Розробити програму обчислення значення виразу:

 

 

 

n

 

 

 

 

 

 

ai

 

 

 

p =

 

i=1

 

}.

 

min{a

 

, i =

 

 

i

1, n

Розв’язання.

 

 

 

 

 

Data

Segment

para 'Data'

n

dw 10

 

 

 

 

 

a

db 13,6,5,4,7 ,5,7,4,10,8

min

db ?

 

 

 

 

 

summa dw ?

 

 

 

 

 

рr

dw ?

 

 

 

 

 

perror

db ‘ min {Ai } =0 ‘,’$’

Data

Ends

 

 

 

 

 

Code

Segment

para 'Code'

Assume cs:Code,ds:Data

Main

Proc far

 

 

 

 

 

 

push DS

 

 

 

 

 

 

sub AX,AX

 

 

 

 

 

push AX

 

 

 

 

 

 

mov AX,Data

 

 

 

mov DS,AX

 

 

 

 

mov CX,n

 

 

; Кількість елементів масиву А.;у CX.

 

jcxz s4

 

 

 

; Немає послідовності.

 

lea SI,a

 

 

 

; Завантаження відносної адреси масиву А.

 

mov AL,[SI]

; Завантаження першого елемента масиву

 

 

 

 

 

 

; А в AL.

 

inc SI

 

 

 

; Збільшити на 1 вміст регістра SI.

 

xor AH,AH

 

; Очистити старшу частину регістра AX.

 

mov DI,AX

 

 

; Регістр для накопичення суми членів

 

 

 

 

 

 

; послідовності.

 

mov BX,AX

 

; У BX мінімальний член послідовності.

 

dec CX

 

 

 

; Зменшити на 1 вміст регістра CX.

 

jcxz s5

 

 

 

; Перехід, якщо СХ = 0.

s1:

mov [SI],AL

; Завантаження елемента масиву А в AL.

 

inc SI

 

 

 

; Збільшити на 1 вміст регістра SI.

83

 

 

add DI,AX

; Підсумування елемента масиву А.

 

 

cmp BL,AL

; Пошук найменшого елемента масиву А.

 

 

jb s3

 

 

 

 

 

mov BX,AX

 

 

 

 

s3:

loop s1

; Цикл.

 

 

 

 

cmp BX,0

; Перевірка, щоб не ділити на 0.

 

 

jne s2

; Мінімальних елемент = 0

 

s4:

lea DX,perror

 

 

 

 

 

int 21h

 

 

 

 

 

ret

 

 

 

 

s2:

mov AX,DI

; Суму елементів записати в регістр AX.

 

 

cwd

; Розширити вміст AX до (DX,AX).

 

 

div BX

; Суму елементів масиву на мінімальний

 

 

 

; елемент.

 

 

 

 

mov рr,AX

; Результат присвоїти змінній Рr.

 

 

ret

 

 

 

 

s5:

mov AX,1

; Якщо масив складається з одного елемента

 

 

mov рr,AX

; то змінній Рr присвоїти 1.

 

 

ret

 

 

 

 

Endp

 

 

 

 

 

Code

Ends

 

 

 

 

 

End Main

 

 

 

 

 

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

 

1. Розробити програму обчислення виразу :

 

Вираз

 

Змінні

 

 

f=(d*c-1)/(c*a-

 

 

 

1

10)+a*b/c+a*c%d+b/d

 

a=6fh b=14 c=-93 d=46h

 

2

f=a-b*(c+(d/a)*b%(c%d-a)/b)+c/d

a=58h b=45h c=-66h d=-5fh

 

3

f=(a-b+(c+(d-a*b/c*d)/a/b)*c)/d

a=61 b=19 c=15 d=-44h

 

4

f=a-(b/(c*d/a%(b+c*d))/a+b)+c%d

a=45 b=70 c=-75 d=2eh

 

5

f=a-b/c+((d/a+(b/c)*d%a+b*c)+d)

a=35 b=31 c=1bh d=59

 

6

f=a-b*((c+d/a+(b+c)*d+a)%b)-c-d

a=60 b=71 c=51h d=-19h

 

7

f=a-b*(c%(d+(a-b)/c)+d/a)*b*c/d

a=47 b=41 c=-1fh d=18

 

8

f=a*(b/c-(d*(a)-b)+c/d/a-b+c+d)

a=70 b=31 c=-6ah d=-2bh

 

9

f=a+(b-c%(d-(a/b-c)*d-a)+b*c)+d

a=11h b=30 c=47 d=51

 

10

f=(a*(b+c))*d/(a+b/c+d*a%b-c)-d

a=53h b=1fh c=34 d=-39

 

11

f=(a-b-(c+d)*(a+b)/c%d+a)*b/c+d

a=72 b=79 c=-15 d=89

 

12

f=a-b+(c-d%(a-b)/(c+d)%a-b+c)*d

a=53h b=3eh c=-72 d=-73

 

84

 

 

 

 

13

f=a/(b+c-(d-a/b+(c*d)+a))*b-c%d

a=28h b=55 c=67h d=42

14

f=(a+b*(c-(d+a)/b)%c+d*a-b+c)/d

a=4fh b=35 c=-18h d=-69

15

f=a/b*c+((d/(a*b+c-d*a+b)-c))-d

a=91 b=31h c=54h d=-88

16

f=a-b*c*d/((a-b)-(c/d+a/b)%c-d)

a=94 b=38 c=59h d=57

17

f=a-b%c*(d+((a+b))/c+d)+a-b/c/d

a=5ah b=66 c=-61h d=-6ch

18

f=(a-b-c*((d-a)/b)%c+d)*a+b/c+d

a=4fh b=36 c=74 d=39h

19

f=a%(b+c%d+(a-(b/c))+d+a*b)/c+d

a=6eh b=33 c=-98 d=53

20

f=a-(b/(c*d+(a/b)/c/d)%a+b+c)*d

a=46h b=64 c=60 d=-32

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

 

 

 

 

 

 

a + b −1

 

1)

a +

 

 

 

 

 

 

ab

, a, b – цілі;

 

 

a

2

+1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2)

1

+

 

 

1

 

 

( x + y ) , x, y – цілі;

 

 

 

 

 

 

 

 

 

x

2

 

 

 

xy

 

 

+1

 

 

 

 

 

 

n +1

 

 

1

 

3)n 2 + m 2 +1 ( m +1)(n +1) , n, m - цілі;

 

 

ab+ (a b)(a + b)−1

− 5 , a, b – цілі;

4)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

a

2

+ b

2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

n +1

 

5

 

 

 

(n

 

 

 

 

 

5)

 

 

 

 

 

+

 

 

, n, m – цілі;

+ m)

 

 

 

 

 

 

 

 

 

 

 

 

m+1

m

 

 

 

xy +

x + y 2 + 3

 

6)

 

 

 

 

 

 

 

 

 

, x, y – цілі;

 

 

x

2

+ 5

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

7)

 

 

 

 

 

 

+1 ( m n) , n, m –цілі;

 

+ m

2

+1

 

n

 

 

 

 

 

 

 

 

ab

 

 

 

 

 

 

+

 

 

 

 

8)

 

a 2 +1

b 2 +1 , a, b – цілі;

 

 

 

 

2

 

 

 

5 x + y 2

 

 

 

( xy)

 

 

 

 

 

 

9)

 

 

y 2 +1 , x, y – цілі;

 

 

 

 

 

 

 

10)

5 +

 

 

b

+ (a b)

1

, a, b – цілі;

 

 

 

 

 

b

2

+1

a + b

 

 

 

 

 

 

 

 

11)

 

xy 2 + x 2 y

( x y) , x, y – дійсні;

 

xy +1

 

 

 

 

 

 

85

 

 

 

 

 

 

 

 

 

 

 

 

n +1

2

 

12)

 

( m n)

 

 

 

 

 

 

n

+ 5 , n, m – цілі;

 

n + m +1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

y

2

+

4

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

13)

 

 

 

 

 

 

 

 

 

 

 

+1 x

, x, y – цілі;

 

2

+2 x +5

 

x

 

 

 

 

 

 

 

 

 

 

 

1

 

 

 

 

 

 

1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

14)

 

a 2

 

 

 

 

 

 

 

 

 

b 2 + ab +1 , a, b – цілі;

 

+ ab +1

 

 

 

 

 

5

 

 

 

 

 

 

 

 

 

 

2

 

15)

 

 

 

 

 

 

 

( m + n )

+ n

, n, m – цілі.

 

n + m

2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

86

Лабораторна робота № 7 Обробка символьних рядків за допомогою ланцюжкових команд

Мета: вивчення можливостей обробки символьних рядків за допомогою ланцюжкових команд.

План заняття.

1.Особливості команд обробки ланцюжків.

2.Напрямок обробки ланцюжків. Команди зміни значення прапорця

DF ( CLD, STD ).

3.Префікси повторення ( REP, REPE, REPZ, REPNE, REPZE ).

4.Команди обробки ланцюжків (MOVS, CMPS, SCAS, LODS, STOS).

Теоретичні відомості

1.Особливості команд обробки ланцюжків

На практиці часто необхідно обробляти дані розміром або байт,

або слово, або подвійне слово декілька разів підряд. Для цього можна використати ланцюжкові команди. Ланцюжок – це набір контекстнопов’язаних байтів, слів, або подвійних слів, які знаходяться в сусідніх комірках пам’яті. В системі команд процесора є п’ять команд, призначених для обробки одного елемента ланцюжка (байта, слова, подвійного слова) і автоматичного переходу до наступного елемента. Таким ланцюжковим командам може передувати префікс повторення, який забезпечує повторну дію команди над наступним елементом (тоді обов’язково використовується лічильник повторення ланцюжкової команди – регістр cx або ecx, який потрібно ініціалізувати перед використанням ланцюжкової команди). Завдяки префіксу ланцюжки обробляються значно швидше, ніж при організації програмного циклу. Повторення розраховано на максимальну довжину ланцюжка (64 Кбайтів для реального режиму, 4 Гбайтів для захищеного режиму) і може призупинятися за декількома умовами. Крім того, повторювані ланцюжкові команди можна переривати і відновлювати їх виконання.

Команди можуть визначати ланцюжок-джерело src, ланцюжокприймач dst або обидва операнди одночасно. Вважається, що операнд джерело знаходиться в поточному сегменті даних, який визначається сегментним регістром DS, але можлива заміна сегмента. Ланцюжокприймач повинен знаходитися тільки в поточному додатковому сегменті даних, який визначається сегментним регістром ES, і заміна сегмента не дозволяється. Можна вказувати операнди ланцюжкових команд для кращої наочності програм, однак процесор і транслятор не

87

використовують їх для адресації ланцюжків. Натомість вміст регістра SI|ESI завжди вважається адресою (зміщенням) поточного елемента ланцюжка-джерела, а вміст регістра DI|EDI – зміщенням поточного елемента ланцюжка-приймача. Ці регістри потрібно відповідно ініціалізувати до виконання ланцюжкової команди.

При виконанні ланцюжкової команди вміст регістрів SI|ESI та DI|EDI автоматично модифікується так, щоб адресувати наступні елементи ланцюжків. Прапорець напрямку DF визначає автоінкремент (df = 0) або автодекремент (df = 1) індексних регістрів. Величина інкремента/декремента залежить від розміру елемента ланцюжка і дорівнює 1, 2 або 4, коли елементами ланцюжка є відповідно байт, слово або подвійне слово.

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

2.Напрямок обробки ланцюжків. Команди зміни значення прапорця

DF( CLD, STD )

Напрямок обробки ланцюжка від менших адрес елементів до більших або навпаки, від більших адрес до менших, визначається значенням прапорця df. Якщо значення прапорця df = 0, то напрямок обробки ланцюжка від менших адрес елементів до більших. Якщо значення прапорця df = 1, то напрямок обробки ланцюжка від більших адрес елементів до менших. Для того, щоб установити те або інше значення прапорця df, використовуються команди CLD та STD.

Команда встановлення прапорця df, таким, що дорівнює 1.

Загальний вигляд команди

STD.

Алгоритм роботи: Значення df = 1.

Команда встановлення прапорця df, таким, що дорівнює 0.

Загальний вигляд команди

CLD

Алгоритм роботи: Значення df = 0.

Значення прапорця df потрібно встановити до використання ланцюжкової команди.

3. Префікси повторення ( REP, REPE, REPZ, REPNE, REPZE )

88

Префікси повторення використовуються для циклічного виконання ланцюжкових команд. Наприклад, наявність цього префікса дозволяє передати ланцюжок довільної довжини (довжина якого не перевищує максимальної) при відповідній ініціалізації регістрів DS:[SI|ESI], ES:[DI|EDI] та CX|ECX.

Префікс повторення має п’ять мнемокодів: REP, REPE, REPZ, REPNE і REPNZ. Вони визначають тільки два коди префікса 0f2h та 0f3h і введені для кращої передачі змісту команди.

Префікс REP використовується з командами MOVS і STOS, які не впливають на прапорці. Цей префікс означає: “повторювати, поки не досягнуто кінця ланцюжка”, тобто доти, поки вміст регістра CX|ECX не досягне 0. Префікси REPE|REPZ діють однаково і застосовуються з командами CMPS і SCAS та враховують стан прапорця zf, який модифікується цими командами: операція повторюється, якщо вміст CX|ECX не дорівнює нулеві і zf=1. Префікси REPNE|REPNZ діють однаково, але для повторення операції потрібен ненульовий вміст CX|ECX та zf=0.

5. Команди обробки ланцюжків (MOVS, CMPS, SCAS, LODS, STOS)

Команда передачі ланцюжка MOVS має такий загальний

вигляд:

MOVS dst,src; dst=(src), SI|ESI=(SI|ESI)+h, DI|EDI=(DI|EDI)+h.

Алгоритм роботи: команда передає або байт, або слово, або подвійне слово з ланцюжка src, який адресується регістрами DS:[SI|ESI, в ланцюжок dst, який адресується регістрами ES:[DI|EDI], і коректує вміст регістрів SI|ESI і DI|EDI на величину h, значення якої – число зі знаком, яке залежить від значення прапорця df і може дорівнювати ±1 ,

±2 , ±4 . Якщо використовується префікс повторення, то команда MOVS здійснює блокову передачу пам’ять – пам’ять. В програмі перед командою з префіксом повторення потрібно ініціалізувати регістр-лічильник CX|ECX. Транслятори допускають використання мнемонік з явною специфікацією розміру елементів ланцюжків: MOVSB (byte), MOVSW (word), MOVSD (double word).

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

Команда порівняння ланцюжків CMPS має такий загальний

вигляд:

CMPS dst,src; dst=(src)–(dst), SI|ESI=(SI|ESI)+h, DI|EDI=(DI|EDI)+h.

89

Алгоритм роботи: команда віднімає вміст байта, слова або подвійного слова з ланцюжка dst від відповідного елемента ланцюжка src і коректує вміст регістрів SI|ESI і DI|EDI на величину h, значення якої – число зі знаком, яке залежить від значення прапорця DF і може дорівнювати ±1 , ±2 , ±4 . В залежності від результату віднімання модифікуються прапорці, операнди src і dst не змінюються. .Якщо перед командою використовується префікс повторення REPE|REPZ, то команда інтерпретується як “повторювати, поки не досягнуто кінця ланцюжка і поки елементи однакові”. При наявності префікса повторення REPNE|REPNZ операція інтерпретується так: “порівнювати, поки не досягнуто кінця ланцюжка і поки елементи ланцюжка різні”. В програмі перед командою з префіксом повторення потрібно ініціалізувати регістр-лічильник CX|ECX.

Для явної вказівки довжини елементів ланцюжків можливі мнемокоди CMPSB, CMPSW, CMPSD.

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

Команда сканування ланцюжка SCAS має такий загальний

вигляд:

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

Алгоритм роботи: команда віднімає елемент ланцюжка dst (байт, слово, подвійне слово) із вмісту акумулятора (відповідно AL, AX, EAX) і регістр-вказівник DI|EDI просувається на наступний елемент ланцюжка. За одержаною різницею модифікуються прапорці, причому операнди – акумулятор acc і приймач dst без зміни. З префіксом повторення REPE|REPZ команду можна використовувати для пошуку елемента ланцюжка зі значенням, відмінним від заданого в акумуляторі. Префікс REPNE|REPNZ дозволяє знайти елемент ланцюжка, значення якого збігається зі значенням в акумуляторі. В програмі перед командою з префіксом повторення потрібно ініціалізувати регістр-лічильник CX|ECX.

Мнемоніки SCASB, SCASW, SCASD використовуються, щоб явно вказати довжину (тип) елементів ланцюжка.

Команда завантаження ланцюжка LODS має такий загальний

вигляд:

LODS src; acc=(src), SI|ESI=(SI|ESI)+h.

Алгоритм роботи: команда завантажує елемент ланцюжка src (байт, слово, подвійне слово) в акумулятор і вміст регістра SI|ESI змінює на

90

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