Міністерство освіти та науки України
Кіровоградський Державний Технічний університет
Кафедра програмного забезпечення
Курсова робота
з дисципліни “Програмування на мові ASM-86” на тему:
Реалізація функцій ABS(X), [X], {x}
ЗМІСТ
Вступ
Постановка задачі
Обґрунтування вибору методів розв’язку задачі
Алгоритм програми.
Реалізація програми
Системні вимоги
Інструкція для користувача
Висновки
Використана література
Додаток. Лістинг програми
1. Вступ
У процесі роботи з комп’ютером виникає необхідність роботи з різними видами даних. Так, наприклад, мови високого рівня можуть працювати з цілими, дробовими числами, символами, рядками і т.д. Програмуючи на мові асемблера, найчастіше маємо справу з цілими числами. Стандартні розміри чисел такі: 8-розрядні (байти), 16-розрядні (слова), 32-розрядні (подвійні слова). У пам’яті вони записуються послідовно, починаючи з молодшого байта.
Також в асемблері є можливість роботи з дробовими числами. Для роботи з ними використовується математичний сопроцесор або його емулятор (він входить до складу основного процесора починаючи з 486DX). Цей сопроцесор оперує з цілими числами та з числами з плаваючою комою. Використовуються 32-, 64- та 80-розрядні формати запису чисел. Наприклад, формат 32-бітного дробового числа має такий формат (тип float в С, REAL в PASCAL):
Найстарший біт – знак мантиси (0- “+”, 1- “-“).
Далі – 8 розрядів порядку, до якого додано 127.
Потім – 23-розрядна мантиса.
Отже, з цими числами можуть робити різні операції як сопроцесор, так і основний процесор.
2. Постановка задачі
Необхідно створити програму, яка б перетворювала ціле число в дробове і навпаки, а також функції [x], {x}, |X|.
3. Обґрунтування вибору методів розв’язку задачі
У зв’язку з тим, що не на кожній машині присутній сопроцесор, то програма буде оперувати з 32-розрядними числами з плаваючою комою, які розташовані у простій пам’яті. Вони матимуть стандартний запис, і тому з ними може проводити роботу і сопроцесор, і програми, які його замінюють.
Робота буде полягати в конвертуванні бітів у числах і деяких обчисленнях. Для цього використовуються команди мови асемблер передачі інформації, обчислень, зсувів та логіки. Також, для демонстрації роботи програми використовується завантаження даних в регістри сопроцесора (fld, fst).
4. Алгоритм програми
а) Алгоритм перетворення цілого числа в дійсне
1. Обчислити знак числа, якщо число від’ємне – обернути його.
2. Записати число без знака у вигляді мантиси.
3. Взяти початкове значення порядку – 127.
4. Зсувати мантису вліво до тих пір, поки старший біт не стане рівним 1. Зсунути ще раз (старший біт мантиси ігнорується). Збільшити порядок на кількість зсувів.
5. Скомбінувати отримані знак, мантису і порядок у відповідності з форматом.
б) Алгоритм переведення числа з дійсного в ціле
1. Визначити знак дійсного числа.
2. Визначити мантису і порядок
3. Від порядку відняти 127 – це дорівнює Х.
4. Зсунути мантису на Х вправо – це і буде ціле число.
в) Функція [Х]
1. Перетворити дійсне число в ціле
2. Результат знову перетворити в дійсне
г) Функція |X|
1. Поставити в 0 знак мантиси дробового числа
д) Функція {X}
1. Виділити цілу і дробову частину (аналогічно як при переведенні дійсного в ціле) і відкинути цілу.
2. Взяти порядок рівний 127.
3. Зсувати мантису вліво поки старший біт рівний 1 не вийде за межі мантиси.
4. Зменшити порядок на кількість зсувів.
5. Записати результат у відповідний формат.
5. Реалізація програми
Програма написана на мові ASM-86 з використанням команд сопроцесора та команд процесора 286/386. Вона складається з функцій, які мають цілі вхідні та вихідні дані в регістрі AX, а дробові дані – за адресою DS:SI та ES:DI. Для роботи необхідно записати у відповідні регістри дані або їх адреси, викликати функції і прочитати результат з вказаного місця.
Програма компілюється Turbo Assembler, зв’язується за допомогою TLINK.
6. Системні вимоги
- Математичний сопроцесор (для демонстрації)
- Мікропроцесор Intel 80386 або старший.
- Для перегляду результатів – Turbo Debugger або інший відлагоджувач.
7. Інструкція для користувача
Програма для роботи з числами містить 5 функцій. Розглянемо приклади їх викликів.
Необхідно описати такі дані:
r dd 0 ;дійсне число
I dw 0 ;ціле число
а) перетворення цілого в дійсне:
mov ax,word ptr [I]
mov di,seg r
mov es,di
mov di,offset r
call WORD_TO_REAL
б) перетворення дійсного в ціле
mov ax,word ptr [I]
mov si,seg r
mov ds,si
mov si,offset r
call REAL_TO_WORD
в) визначення [X]
mov si,seg r
mov ds,si
mov si,offset r
call REAL_TRUNC
г) визначення {X}
mov si,seg r
mov ds,si
mov si,offset r
call REAL_REAL
д) визначення {X}
mov si,seg r
mov ds,si
mov si,offset r
call REAL_ABS
8. Висновки
Отже, є розробленою програма, яка виконує операції з дробовими та цілими числами – конвертування, {X} |X| [X]. Був розглянутий формат дійсних чисел, і наведені алгоритми розв’язку.
9. Використана література
1. Ровдо А. А. Микропроцессоры от 8086 до Pentium III Xeon и AMD-K6-3. М., ДМК, 2000
Додаток. Лістинг програми
.model small
.stack 100
.486
.data
f dd 0
.code
start:
jmp begin
;------------------------------------------------------------
;обчислення функцiї ABS(x) - DS:SI - REAL
REAL_ABS proc
push bx
mov bh,byte ptr ds:[si+3]
and bh,7fh
mov byte ptr ds:[si+3],bh
pop bx
ret
REAL_ABS endp
;------------------------------------------------------------
;конвертор REAL в DS:SI в WORD (AX)
REAL_TO_WORD proc
jmp start_proc
x dw 0 ;тимчасовий параметр AX
start_proc:
pusha
;1)видiлити окремо знак, порядок i мантису
; bh - знак, bl - порядок, ax - мантиса
mov bh,byte ptr ds:[si+3]
and bh,80h ;видiлили знак
mov bl,byte ptr ds:[si+3]
shl bl,1
mov ah,byte ptr ds:[si+2]
shr ah,7
or bl,ah ;видiлили порядок
mov ah,byte ptr ds:[si+2]
mov al,byte ptr ds:[si+1]
shl ax,1 ;видiлили мантису
cmp bl,127 ;перевiрка на нуль
jb res_zero
sub bl,127
mov cl,15
sub cl,bl ;cl-кiлькiсть зсувiв вправо мантиси
stc ;старший розряд завжди 1
rcr ax,1
shr ax,cl
mov word ptr cs:[x],ax ;... i отримаємо результат!
cmp bh,0 ;враховуємо знак
je res_ok
neg ax
mov word ptr cs:[x],ax
jmp res_ok
res_zero:
mov word ptr cs:[x],0
res_ok:
popa
mov ax,word ptr cs:[x]
ret
REAL_TO_WORD endp
;---------------------------------------------------------------
;конвертор 16-бiтного слова в AX в коротке дiйсне es:di (4 байта)
WORD_TO_REAL proc
pusha
;нуль?
cmp ax,0
jne no_zero
mov dword ptr es:[di],0
popa
ret
no_zero:
push di
;1) якщо d15=1 - bh=80h (знак), iнакше bh=0
xor bh,bh
test ax,8000h
jz plus
neg ax
mov bh,80h
plus:
;2)зсунути AX влiво так, щоб старша одиниця була в CF.
; пiдрахувати кiлькiсть зсувiв
xor di,di
mov cx,16
shift: inc di
shl ax,1
jc stop_shift
loop shift
stop_shift:
;3)обчислити порядок: bl=127+16-di
mov cx,di
mov bl,127+16
sub bl,cl
pop di
;отже,маємо:bh-знак,bl-порядок,ax-мантиса
;ставимо найстарший байт (3) в 0
mov byte ptr es:[di],0
;ставимо молодший байт: знак+7 старших бiтiв порядку
mov dl,bh
push bx
shr bl,1
or dl,bl
pop bx
mov byte ptr es:[di+3],dl
;ставимо 1-й байт: останнiй байт порядку i 7 ст байт мантиси
and bl,1
shl bl,7
shr ax,1
or bl,ah
mov byte ptr es:[di+2],bl
;ставимо 2-й байт: молодшi 8 байт мантиси
mov byte ptr es:[di+1],al
popa
ret
WORD_TO_REAL endp
;------------------------------------------------------------
;обчислення функцiї [X] - DS:SI - REAL
REAL_TRUNC proc
push ax
call REAL_TO_WORD
call WORD_TO_REAL
pop ax
ret
REAL_TRUNC endp
;------------------------------------------------------------
;обчислення функцiї {X} - DS:SI - REAL
REAL_REAL proc
push eax
push edx
push bx
push cx
;в EDX записати у зворотньому порядку число
mov dh,byte ptr ds:[si+3]
xor bh,bh
mov bl,dh
shl bl,1
adc bh,0
shl bh,7
mov dl,byte ptr ds:[si+2]
mov ah,dl
and ah,80h
shr ah,7
or bl,ah ;в BH - знак, в BL - порядок, в EDX - число
shl edx,16
mov dh,byte ptr ds:[si+1]
mov dl,byte ptr ds:[si]
cmp bl,127
jb stop_tr ;це вже число <0!
shl edx,9 ;прибрати все зайве (знак i порядок)
sub bl,127 ;кiлькiсть зсувiв (бiтiв з цiлою частиною)
mov cl,bl
shl edx,cl ;вiдкинути цiлу частину
;зараз в EDX - дробова частина
;тепер обчислюємо порядок
mov bl,127
shift_l:
dec bl
shl edx,1
jnc shift_l ;отже, тепер порядок в bl, а в edx готова мантиса
;тепер зсунути EDX вправо на 9
shr edx,9
xor eax,eax
mov al,bh
shl eax,1
or al,bl
shl eax,23
or edx,eax ;i комбiнуємо!
;тепер записати в пам`ять
mov byte ptr ds:[si],dl
mov byte ptr ds:[si+1],dh
shr edx,16
mov byte ptr ds:[si+2],dl
mov byte ptr ds:[si+3],dh
stop_tr: ;вихiд
pop cx
pop bx
pop edx
pop eax
ret
REAL_REAL endp
;------------------------------------------------------------
begin:
mov ax,@data
mov es,ax
mov ds,ax
mov di,offset f
mov si,offset f
;mov ax,-32768
;call WORD_TO_REAL
;fst dword ptr es:[di]
;call REAL_TRUNC
fst dword ptr es:[di]
;call REAL_TO_WORD
call REAL_REAL
fld dword ptr es:[di]
mov ah,4ch
int 21h
end start