Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабы по Организации ЭВМ и систем.doc
Скачиваний:
12
Добавлен:
06.05.2019
Размер:
290.82 Кб
Скачать

Лабораторная работа 9

cos(x) * sin(x) + cos(x)^2 * sin(x)^2 + cos(x)^3 * sin(x)^3

.286c

.387

.MODEL small

.stack 100h

.data

msg db "ESC-exit",13,10,10,"cos(x) * sin(x) + cos(x)^2 * sin(x)^2 + cos(x)^3 * sin(x)^3",13,10,"Enter X (0...999) ",13,10,"$"

msg2 db "Calculating...",13,10,"$"

Pi2 DD 360 ;360 градусов

buff db 4 dup (0) ;буфер

x dw 0 ;пременная x

.code

;=========================================================

;Enter_digit - процедура ввода чисел

;=========================================================

enter_digit proc

xor si,si

xor cx,cx

xor bx,bx

@enter:

mov ah,0 ; Ожидаем нажатия и

int 16h ; читаем код клавиши

cmp al,1bh ;если esc -выход

je exit

cmp al,30h ;сравниваем в промежутке 0-9

jb @f

cmp al,40h

jnb @f

mov ah,0eh ; Выводим символ

int 10h ; на экран

mov [buff+si],al ;записать символ

inc si

inc bx

cmp bx,3 ;если равно 3,то выйти из цикла

je @f

jmp @enter

@@:

mov al,10

mov ah,0eh ; Выводим символ

int 10h ; на экран

ret

enter_digit endp

StrToHex proc

xor cx,cx

xor dx,dx

mov si,offset buff ;перевод строки из буфера в HEX

@lp1: xor ax,ax

lodsb ;берем cимвол(байт)

test al,al ;если это нулев байт, то заканчиваем

jz @ex

cmp al,'9' ;Если это не цифра, то пропускаем

jnbe @lp1

cmp al,'0' ;Если это не цифра, то пропускаем

jb @lp1

sub ax,'0' ;получаем цифровое значение

shl dx,1 ;сдвиг на 1=умножаем сумму на 2

add ax, dx ;прибавляем к ax

mov cl,2

shl dx, cl ;сдвиг на 2=умножение на 4

add dx, ax ;прибавляем текущее значение

jmp @lp1

@ex:

mov ax,dx

mov [x],ax ;результат преобразования число в x

ret

StrToHex endp

outfloat proc near

push ax

push cx

push dx

; Формируем кадр стэка, чтобы хранить в нём десятку

; и ещё какую-нибудь цифру.

push bp

mov bp, sp

push 10

push 0

; Проверяем число на знак, и если оно отрицательное,

ftst

fstsw ax

sahf

jnc @of1

; то выводим минус

mov ah, 02h

mov dl, '-'

int 21h

; и оставляем модуль числа.

fchs

; Пояснение далее пойдёт на примере. ; ST(0) ST(1) ST(2) ST(3) ...

; Отделим целую часть от дробной. ; 73.25 ... что-то не наше

@of1: fld1 ; 1 73.25 ...

fld st(1) ; 73.25 1 73.25 ...

; Остаток от деления на единицу даст дробную часть.

fprem ; 0.25 1 73.25 ...

; Если вычесть её из исходного числа, получится целая часть.

fsub st(2), st ; 0.25 1 73 ...

fxch st(2) ; 73 1 0.25 ...

; Сначала поработаем с целой частью. Считать количество цифр будем в CX.

xor cx, cx

; Поделим целую часть на десять,

@of2: fidiv word ptr [bp - 2] ; 7.3 1 0.25 ...

fxch st(1) ; 1 7.3 0.25 ...

fld st(1) ; 7.3 1 7.3 0.25 ...

; отделим дробную часть - очередную справа цифру целой части исходного числа,-

fprem ; 0.3 1 7.3 0.25 ...

; от чатсного оставим только целую часть

fsub st(2), st ; 0.3 1 7 0.25 ...

; и сохраним цифру

fimul word ptr [bp - 2] ; 3 1 7 0.25 ...

fistp word ptr [bp - 4] ; 1 7 0.25 ...

inc cx

; в стэке.

push word ptr [bp - 4]

fxch st(1) ; 7 1 0.25 ...

; Так будем повторять, пока от целой части не останется ноль.

ftst

fstsw ax

sahf

jnz short @of2

; Теперь выведем её.

mov ah, 02h

@of3: pop dx

; Вытаскиваем очередную цифру, переводим её в символ и выводим.

add dl, 30h

int 21h

; И так, пока не выведем все цифры.

loop @of3 ; 0 1 0.25 ...

; Итак, теперь возьмёмся за дробную часть, для начала проверив её существование.

fstp st(0) ; 1 0.25 ...

fxch st(1) ; 0.25 1 ...

ftst

fstsw ax

sahf

jz short @of5

; Если она всё-таки ненулевая, выведем точку

mov ah, 02h

mov dl, '.'

int 21h

; и не более шести цифр дробной части.

mov cx, 6

; Помножим дрообную часть на десять,

@of4: fimul word ptr [bp - 2] ; 2.5 1 ...

fxch st(1) ; 1 2.5 ...

fld st(1) ; 2.5 1 2.5 ...

; отделим целую часть - очередную слева цифру дробной части исходного числа,-

fprem ; 0.5 1 2.5 ...

; оставим от произведения лишь дробную часть,

fsub st(2), st ; 0.5 1 2 ...

fxch st(2) ; 2 1 0.5 ...

; сохраним полученную цифру во временной ячейке

fistp word ptr [bp - 4] ; 1 0.5 ...

; и сразу выведем.

mov ah, 02h

mov dl, [bp - 4]

add dl, 30h

int 21h

; Теперь, если остаток дробной части ненулевой

fxch st(1) ; 0.5 1 ...

ftst

fstsw ax

sahf

; и мы вывели менее шести цифр, продолжим.

loopnz @of4 ; 0 1 ...

; Итак, число выведено. Осталось убрать мусор из стэка.

@of5: fstp st(0) ; 1 ...

fstp st(0) ; ...

; Точнее, стэков.

leave

pop dx

pop cx

pop ax

ret

outfloat endp

start:

mov ax,@data ; взять адрес сегмента данных

mov ds,ax ; занести в сегментный регистр данных

mov dx,offset msg ; взять адрес строки msg

mov ah,9 ; функция 09h в AH запись строки в устройство стандартного вывода

int 21h ; вызов дос прерывания

call enter_digit

call StrToHex

mov dx,offset msg2 ; взять адрес строки msg2

mov ah,9 ; функция 09h в AH запись строки в устройство стандартного вывода

int 21h ; вызов дос прерывания

finit ;инициализация сопроцессора

FLDPI ;загрузить число Пи в st(0)

FLDPI ; и st(1)

FADD st(0),st(1) ;сложить =2Пи

fidiv Pi2 ;разделить на 360

fild x ;загрузить х как вещественное в вершину стека st(0)

fmul st(0),st(1) ;умножить x на радиан,получаем радианный угол

fsincos ;находим синус и косинус

fmul ;sin*cos

fld st(0) ;копия sin*cos результат в st(0)

fld st(0)

fmul ;st(0)=sin^2*cos^2

fld st(0)

fld st(2) ;st(1),s(0)=sin^2*cos^2

fmul ;перемножаем st(0) и st(1);st(0)=sin^3*cos^3

faddp st(1),st(0) ;складываем с выталкиванием из st(0). st(0)=sin^3*cos^3 и sin^2*cos^2

faddp st(1),st(0) ;складываем с выталкиванием из st(0). st(0)=sin^3*cos^3 + sin^2*cos^2 +sin*cos

call outfloat ;процедура вывода результата

mov ax,0C07h ; ожидание шажатия клавиши

int 21h

exit:

mov ax, 4C00h ; функция корректного выхода из программы

int 21h ;

end start