Вещественное деление двух чисел с помощью сопроцессора, затем вывод результата на экран. Компилятор TASM
Уже несколько дней хочу научится орудовать вещественными числами, нужно для лабораторной. Даже нашёл алгоритм вывода на экран, понял его, и думал, что всё заработает. Программа принимает 2 числа, для примера x = 125, y = 4. z = x/y = 31.25. Но нет, выводит только 31.00. Другие числа, конечно, проверил. Помогите, пожалуйста, 2 дня потратил , сил нет. Уже думал реализовать деление в столбик)
DosSeg
include D:\tasm.2_0\tasm\io.asm
.model small
.stack 100
.data
inpX db "Enter X: ",'$'
inpY db "Enter Y: ",'$'
outZ db "Z = ",'$'
x dd ?
y dd ?
.code
.startup
.286C
mov ah, 9
lea dx, inpX
int 21h
inint ax ; макрокоманда inint осуществляет ввод числа с клавиатуры
mov word ptr x, ax
mov ah, 9
lea dx, inpY
int 21h
inint ax
mov word ptr y, ax ; ввод y
mov ah, 9
lea dx, outZ
int 21h
push bp
mov bp, sp
push 10 ; на 10 будем делить у умножать
push 0 ; ещё одно место под число
finit
fld y
fld x
fdiv st(0), st(1) ; s(0) = s(0) / s(1) (
ftst ; сравнение s(0) с нулём
fstsw ax
sahf
jnc DROB ; если > 0, то пропускаем вывод минуса
mov ah, 02h
mov dl, '-'
int 21h
fchs ; модуль числа
DROB: ; пусть x = 125, y = 4, тогда: 31.25 8 ...
fld1 ; 1 31.25
fld st(1) ; 31.25 1 31.25 8 ...
fprem ;остаток от деления на 1 в st(0) ; 0.25 1 31.25 8 ...
fsub st(2), st(0) ; целая часть в st(2) 0.25 1 31 8 ...
fxch st(2) ;теперь st - целая часть ; 31 1 0.25 8 ...
xor cx, cx
CEL:
fidiv word ptr [bp - 2] ; делим целую часть на 10 3.1 1 0.25 ...
fxch st(1) ; 1 3.1 0.25 ...
fld st(1) ; 3.1 1 3.1 0.25 ...
fprem ; 0.1 1 3.1 0.25 ...
fsub st(2), st ; 0.1 1 3 0.25 ...
fimul word ptr [bp - 2] ; 1 1 3 0.25 ...
fistp word ptr [bp - 4] ; 1 3 0.25 ...
inc cx
push word ptr [bp - 4] ; сохраним полученную цифру в стек
fxch st(1) ; 3 1 0.25 ...
ftst
fstsw ax
sahf
jnz short CEL ; повторяем, пока st(0) != 0
mov ah, 02h
OUT1:
pop dx ; dx = 3, dx = 1
add dl, 30h ; перевод в ASCII
int 21h
loop OUT1 ; CX = количеству цифр в целой части
fstp st(0) ; 1 0.25 ...
fxch st(1) ; 0.25 1 ...
ftst
fstsw ax
sahf
jz short CLEAR ; если нет дробной части, то точку не ставить
mov ah, 02h
mov dl, '.'
int 21h
mov cx, 6 ; максимум 6 знаков после запятой
DROB1:
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 ...
fstp [bp - 4] ; 1 0.5 ...
mov ah, 02h
mov dl, [bp - 4] ; [bp-4] = 2, [bp-4] = 5
add dl, 30h
int 21h
fxch st(1) ; 0.5 1
ftst
fstsw ax
sahf
loopnz short DROB1 ; повторять пока s(0) != 0 и cx != 0
CLEAR:
fstp st(0)
fstp st(0)
add sp, 4
pop bp
.exit 0
end