Міністерство освіти та науки України
Кіровоградський Державний Технічний університет
Кафедра програмного забезпечення
Курсова робота
з дисципліни “Програмування на мові 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--PAGE_BREAK--
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 продолжение
--PAGE_BREAK--
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; це вже число
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