Реалізація функцій ABS(X), [X], {x}

Міністерство освіти та науки України

Кіровоградський Державний Технічний університет

Кафедра програмного забезпечення

















Курсова робота

з дисципліни “Програмування на мові 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