Міністерство освіти та науки України
Кіровоградський Державний Технічний університет
Кафедра програмного забезпечення
Курсова робота
з дисципліни “Програмування на мові ASM-86”
на тему:
“Реалізація функцій ABS (X), [X], {x}
Зміст
3. Обґрунтування вибору методів розв’язку задачі
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 функцій. Розглянемо приклади їх викликів.
Необхідно описати такі дані:
rdd0; дійсне число
Idw0; ціле число
а) перетворення цілого в дійсне:
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. Використана література
Ровдо А.А. Микропроцессоры от 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