МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”
Кафедра САПР
Звіт про виконання лабораторної роботи №8
на тему: “ АРИФМЕТИЧНІ ОПЕРАЦІЇ МІКРОПРОЦЕСОРА Intel 8086(80286) ”
з курсу: “ Комп’ютери та мікропроцесорні системи ”
Виконав
студент групи КН-3
Львів - 2006
1. МЕТА РОБОТИ
Вивчити основні арифметичні операції мікропроцесора Intel 8086(80286).
2. КОРОТКІ ТЕОРЕТИЧНІ ВІДОМОСТІ
Арифметичні операції додавання та віднімання проводять за допомогою команд ADD та SUB. Нижче наведені можливі ситуації додавання та віднімання.
ADD AL,BL регістр+регістр
ADD AL,BYTEA регістр+пам’ять
ADD BYTEA,BL пам’ять+регістр
ADD AX,2010H регістр+безпосередні дані
ADD WORDA,2030H пам’ять+безпосередні дані
SUB AX,BX регістр-регістр
SUB AX,WORDA регістр-пам’ять
SUB WORDA,BX пам’ять-регістр
SUB BL,10H регістр-безпосередні дані
SUB WORDA,200H пам’ять-безпосередні дані
де: BYTEA - ім’я константи в пам’яті типу байт,
WORDA - ім’я константи в пам’яті типу слово.
У випадку, коли проводиться багатобайтове додавання чи віднімання, використовують додавання з переносом ADC та команду віднімання з позикою SBB. Їх форма запису аналогічна до команд ADD і SUB.
Особливу увагу необхідно звернути на переповнення, яке може відбутися при використанні вище наведених команд. Для прикладу, результат сумування в регістрі AL може перевищити його ємність і автоматично не переходить в регістр AH. Запобігти такій ситуації можна у випадку проведення сумування в двобайтових регістрах. Щоб перетворити байт у слово використовують команду CBW.
Для прикладу:
CBW ; розширити AL до AX
ADD AX,40H ; додати до AX
Аналогічна ситуація може відбутися і при додаванні двох двобайтових слів, які обмежені значенням від -32768 до +32768.
На відміну від асемблера МП КР580ВМ8080А в асемблері мікропроцесора Intel 8086(80286) присутні команди множення. Множення для беззнакових даних виконується командою MUL, а для знакових - IMUL. Існує дві основні операції множення:
Множення байт на байт . Перший множник міститься в регістрі AL, а другий - в байті пам’яті чи однобайтовому регістрі. Результат операції заноситься в регістр AX.
Приклад:
MUL BL
MUL BYTEA
Дані, які до виконання множення були в регістровій парі AX, не зберігаються.
Множення слова на слово. Перший множник міститься в регістрі AX, а другий - в слові пам’яті чи в регістрі. Після проведення операції, результат заноситься у подвійне слово, зокрема: старша(ліва) частина множення міститься в регістрі DX, а молодша (права) частина - в регістрі AX. Для прикладу приведемо множення регістр на регістр та регістр на пам’ять:
MUL BX
MUL WORDA
На практиці зустрічається ряд нестандартних ситуацій множення. Зокрема, множення на степінь 2. (2,4,8 і т.д.), множення константи розміром байт на константу розміром слово та множення багатобайтових слів. У першому випадку ефективніше організовувати алгоритм множення через зсув вліво на необхідну кількість бітів. При множенні байта на слово, необхідно, за допомогою команди CBW, переписати константу типу байт в слово і лише після цього проводити стандартне множення. Множення великих чисел потребує додаткових дій. Один зі шляхів отримання результату такого множення передбачає множення кожного слова окремо, а потім сумування отриманих результатів. Для прикладу, розглянемо аналогічне множення в десятковому форматі:
2211
22
------
4422
4422
--------
48642
Припустимо, що десяткова арифметика дозволяє перемножи-ти лише двозначні числа. Тоді, можна перемножити 22 і 11 на 22 окремо:
22 11
22 22
--- ---
44 22
44 22
------ ----
484 242
Наступний крок полягає в сумуванні отриманих чисел, але з врахуванням, що перше число 22 представляє сотні. В результаті отримаємо:
48400
242
--------
48642
При побудові асемблерних програм для перемноження багатобайтових констант використовується аналогічнийй алгоритм.
Іншою асемблерною командою МП Intel 8086(80286), яка відсутня в асемблері МП КР580ВН80А, є ділення. Цю операцію можна реалізувати командою DIV для беззнакових даних та IDIV для знакових. Існує дві основні операції ділення:
Ділення слова на байт: Ділене міститься в регістрі АХ, а дільник - в байті пам’яті чи в однобайтовому регістрі. Після ділення залишок отримується в регістрі АН, а частка - в АL.
Ділення подвійного слова на слово: Ділене міститься в регістровій парі DX:АХ, а дільник - в слові пам’яті чи в регістрі. Після ділення залишок отримуємо в регістрі DX, а частка - в АX.
Наведемо ряд прикладів:
DIV BYTEA
DIV BX
IDIV CL
IDIV WORD2
У першому та четвертому прикладах дільник міститься в пам’яті, а в другому та третьому -у регістрах. Результати в АХ, DX:AX, AX та DX:AX відповідно.
Дані, які вводяться з клавіатури представлені в ASCII-форматі. Хоча ASCII-коди зручні для відображення на дисплеї та друку, вони потребують спеціальних перетворень в двійковий формат для арифметичних обрахунків. Так, після сумування в ASCII-форматі необхідно провести корекцію результату командою AAA. Команда AAA коректує вміст регістра АХ а перевіряє праву шістнадцяткову цифру (4 біти) в регістрі AL. Якщо ця цифра знаходиться між A і F або прапорець AF рівний 1, то до регістра AL додається 6, а до регістра АН-1, прапорці F та СF встановлюються в 1. В усіх
випадках команда AAA встановлює в 0 ліву шістнадцяткову цифру в регістрі AL. Для додавання та віднімання даних в ASCII-форматі використовуються стандартні команди додавання та віднімання.
Віднімання даних в ASCII-коді потребує корекції командою AAS. Ця команда коректує вміст регістра АХ та перевіряє праву шістнадцяткову цифру (4 біти) в регістрі AL. Якщо ця цифра знаходиться між A і F або прапорець AF дорівнює 1, то з регістра AL віднімається 6, а з регістра АН -1 , прапорці AF та СF встановлюються в 1. В усіх випадках команда AAS встановлює в 0 ліву шістнадцяткову цифру в регістрі AL. Розглянемо два приклади для додавання та віднімання даних в ASCII-форматі. У першому прикладі розглянемо додавання чисел 7 та 5 в ASCII-форматі. Шістнадцяткове представлення цих цифр 37 та 35, відповідно. Отже:
MOV CL,35H ;
MOV AL,37H ;
MOV AH,00 ; очистити регістр AH
ADD AL,CL ; додати 37 до 35
AAA ; корекція для ASCII-кодів
OR AX,3030H ; результат 3132
В результаті після сумування отримаємо в регістрі AX - 006C,
а після корекції - 0102. Для отримання кінцевого ASCII-представлення достатньо поставити трійки на місце лівих шістнадцяткових цифр. У другому прикладі обчислюється різниця між числами 34Н та 48Н:
MOV AH,00
MOV AL,34H
SUB AL,38H
AAS
Після третього оператора в регістрі AX отримаємо значення 00FC та одиницю в AF. Тому, команда AAS віднімає 6 від регістра AL та 1 від регістра AH і встановлює в 1 прапорці AF і СF. Результат, який має дорівнювати -4, має представлення FF06, тобто десяткове доповнення числа -4.
Множення та ділення в ASCII-форматі проводиться стандартними командами (MUL,DIV), але потребує корекції. Для множення використовується коректуюча команда AAM, а для ділення - AAD. Коректується цими командами вміст регістра AX.
Команда AAM ділить вміст регістра AL на 10 (0AH) і записує частку в регістр AH, а залишок в АL.
Постановка лабораторного завдання
Виконати завдання з лабораторних робіт № 4 та № 5 у вигляді підпрограм на мові Асемблер для мікропроцесора 86. Дані для обрахунків вводити з клавіатури. Вибір підпрограм організувати у вигляді меню.
Завдання лабораторної роботи №4: Ввести дані. Проаналізувавши третій розряд першого даного на наявність нуля, при наявності такого виконати (6+5+4+3+2+1), при відсутності – (6-5-4-3-2-1). Результат записати в A.
Завдання лабораторної роботи № 5: Занести в пам’ять послідовно числа 35, 10, 5, 12. Виконати попарно операцію множення способом зсувів (35*10, 5*12). Результат записати в пам’ять.
Текст програми
.model small
.stack 256
.386
.data
mes db 'Laba #8 (vukonav st. grypu KN-313 Pywkar A.)','$'
mes1 db '1. Laba 4',0ah,0dh,'$'
mes2 db '2. Laba 5',0ah,0dh,'$'
mes3 db 'Please make a choice',0ah,0dh,'$'
nl db 0ah,0dh,'$'
vvid db 'Vvedit6 6 chusel (3- rozradnux). Diapazon vvody 0...255',0ah,0dh,'$'
vvid1 db 'Vvedit6 4 chusla. (N.B! chusla 2-rozradni (dodatni zi znakom "+", vidjemni z znakom "-")',0ah,0dh,'$'
vvid2 db 'N.B.-->Chusla pidibratu tak, wob ix dobytok mav ne bilwe 3 rozradiv',0ah,0dh,'$'
rezmes db 'Result: ',0ah,0dh,'$'
t1 db 0
t2 db 0
t3 db 0
d3 db 0
rez dw 0
rez1 dw 0
rez2 dw 0
rez3 dw 0
rez4 dw 0
rez5 dw 0
rez6 dw 0
kil db 0
final dw 0
rezult dw 0
rezult1 db 0
rezult2 db 0
oznaka db 0
ozn1 db 0
ozn db 0
ozn2 db 0
znak db 0
rezz db 0
rezz1 db 0
rezz2 db 0
mn db 10
mn1 db 100
buff db 0
buff1 db 0
buff2 db 0
.code
main proc far
mov ax,@data
mov ds,ax
mov es,ax
mov ah,13h
mov al,1
mov bh,0
lea bp,mes
mov dh,0
mov dl,20
mov bl,10000010b
mov cx,44
int 10h
mov ah,09h
lea dx,nl
int 21h
mov ah,09h
lea dx,mes1
int 21h
mov ah,09h
lea dx,mes2
int 21h
znov:
mov ah,09h
lea dx,mes3
int 21h
mov ah,09h
lea dx,nl
int 21h
mov ah,01h
int 21h
cmp al,31h
je l4
cmp al,32h
je l5
jne znov
;------------------------------------------------------------
l4:
mov ah,09h
lea dx,vvid
int 21h
;------------------------------------------------------------
call inp
mov ax,rez
mov rez1,ax
mov ah,09h
lea dx,nl
int 21h
call inp
mov ax,rez
mov rez2,ax
mov ah,09h
lea dx,nl
int 21h
call inp
mov ax,rez
mov rez3,ax
mov ah,09h
lea dx,nl
int 21h
call inp
mov ax,rez
mov rez4,ax
mov ah,09h
lea dx,nl
int 21h
call inp
mov ax,rez
mov rez5,ax
mov ah,09h
lea dx,nl
int 21h
call inp
mov ax,rez
mov rez6,ax
mov ah,09h
lea dx,nl
int 21h
;-------------------------------------------
mov ah,09h
lea dx,rezmes
int 21h
mov ax,rez1
and ax,00001000b
jz c1
jmp c2
c1:
mov ax,rez6
add ax,rez5
add ax,rez4
add ax,rez3
add ax,rez2
add ax,rez1
mov final,ax
mov kil,16
jmp compare
c2:
mov ax,rez6
sub ax,rez5
sub ax,rez4
sub ax,rez3
sub ax,rez2
sub ax,rez1
mov final,ax
mov kil,16
;-------------------------------------------
compare:
shl final,1
jc one
mov ah,02h
mov dl,30h
int 21h
dec kil
cmp kil,0
jz exit1
jmp compare
one:
mov ah,02h
mov dl,31h
int 21h
dec kil
cmp kil,0
jz exit1
jmp compare
mov ah,09h
lea dx,nl
int 21h
jmp exit1
;-----------------------------------------------
l5:
mov ah,09h
lea dx,vvid1
int 21h
mov ah,09h
lea dx,vvid2
int 21h
mov ah,09h
lea dx,nl
int 21h
call inp1
mov al,rezz
mov rezz1,al
cmp oznaka,1
jne dod
mov ozn,1
jmp y1
dod: mov ozn,0
y1: mov ah,09h
lea dx,nl
int 21h
call inp1
mov al,rezz
mov rezz2,al
cmp oznaka,1
jne dod1
mov ozn1,1
jmp y2
dod1: mov ozn1,0
y2: mov ah,09h
lea dx,nl
int 21h
mov al,ozn
add al,ozn1
mov ozn2,al
mov ah,09h
lea dx,nl
int 21h
;-----------------------------------
jmp noex
exit1: jmp exit
noex: mov al,rezz1
mov dl,rezz2
mul dl
div mn1
mov rezult1,al
mov rezult2,ah ;zaluwok
;mov rezult,ax
mov ah,09h
lea dx,rezmes
int 21h
cmp ozn2,1
jne next1
mov ah,02h
mov dl,'-'
int 21h
jmp next2
next1:
mov ah,02h
mov dl,'+'
int 21h
next2:
mov ah,02h
mov dl,rezult1
add dl,48
int 21h
movzx ax,rezult2
div mn
mov rezult1,al
mov rezult2,ah
mov ah,02h
mov dl,rezult1
add dl,48
int 21h
mov ah,02h
mov dl,rezult2
add dl,48
int 21h
;--------------------------------------------------------------------
mov ah,09h
lea dx,nl
int 21h
mov ah,09h
lea dx,nl
int 21h
call inp1
mov al,rezz
mov rezz1,al
cmp oznaka,1
jne dod2
mov ozn,1
jmp y22
dod2: mov ozn,0
y22: mov ah,09h
lea dx,nl
int 21h
call inp1
mov al,rezz
mov rezz2,al
cmp oznaka,1
jne dod3
mov ozn1,1
jmp y3
dod3: mov ozn1,0
y3: mov ah,09h
lea dx,nl
int 21h
mov al,ozn
add al,ozn1
mov ozn2,al
mov ah,09h
lea dx,nl
int 21h
;-----------------------------------
noex1: mov al,rezz1
mov dl,rezz2
mul dl
div mn1
mov rezult1,al
mov rezult2,ah ;zaluwok
;mov rezult,ax
mov ah,09h
lea dx,rezmes
int 21h
cmp ozn2,1
jne next3
mov ah,02h
mov dl,'-'
int 21h
jmp next4
next3:
mov ah,02h
mov dl,'+'
int 21h
next4:
mov ah,02h
mov dl,rezult1
add dl,48
int 21h
movzx ax,rezult2
div mn
mov rezult1,al
mov rezult2,ah
mov ah,02h
mov dl,rezult1
add dl,48
int 21h
mov ah,02h
mov dl,rezult2
add dl,48
int 21h
exit: mov ah,00h
int 16h
mov ax,4c00h
int 21h
main endp
;-------------------------------------------------------------
inp proc near
pusha
mov ah,01h
int 21h
mov t1,al
sub t1,48 ; перетворюємо символ у число
mov ah,01h
int 21h
mov t2,al
sub t2,48
mov ah,01h
int 21h
mov t3,al
sub t3,48
mov d3,100 ; у d3 заносимо 100
mov al,t1
mul d3 ; множимо al на 100
mov buff,al
mov d3,10
mov al,t2
mul d3
mov buff1,al
mov al,buff
add al,buff1
mov buff2,al
mov al,t3
add al,buff2
cbw
mov rez,ax
popa
ret
inp endp
inp1 proc near
pusha
mov ah,01h
int 21h
mov znak,al
cmp znak,2dh
jne pr
mov oznaka,1
jmp pr1
pr: mov oznaka,0 ; oznaka dodatnogo chusla
pr1: mov ah,01h
int 21h
mov t2,al
sub t2,48
mov ah,01h
int 21h
mov t3,al
sub t3,48
mov d3,10
mov al,t2
mul d3
mov buff1,al
mov al,buff1
add al,t3
mov rezz,al
popa
ret
inp1 endp
end main
Висновки: виконавши дану лабораторну роботу, я освоїв на практиці арифметичні команди мікропроцесора 86.