09.01.2020, 19:10
общий
это ответ
Здравствуйте, Ориса!
Исправленная программа. Ввод-вывод не смотрел. Вроде как работает.
А вот вычисления переделал. Самое интересное место - вычисление exp()
Простого пути не существует, ибо нет такой команды. Для вычисления exp() необходимо выполнить
некоторую последовательность команд, которые оформлены в виде макро
Кое-что по мелочам еще подправил. Сравните...
[code lang=asm h=200] .model small
; Compute e^x. Use the fact that e^x = 2^(x * log2(e)).
EXP MACRO ;Calculate e^st macro
fldl2e ;load const log2(e)
fmulp st(1) ;ST = x*log2(e)
fld st ;Duplicate x*log2(e), now in ST and ST(1)
frndint ;ST = integer part of log2(e)
fsub st(1),st ;ST(1) = fractional part of log2(e)
fxch st(1) ;Now ST = fractional part, ST(1) = integer
f2xm1 ;ST = 2^(frac. part) - 1
fld1 ;Now add 1
faddp st(1),st ;ST=2^(frac. part). ST(1) = int. part, still
fscale ;ST = 2^(frac. part) * 2^(int. part)
; = 2^(frac. + int.) = 2^(x * log(e))
fstp st(1) ;delete st(1)
ENDM
.data
sEnterA db "Enter a = $"
sEnterX db "Enter x = $"
sY db "y = $"
c37 dw 37
c2 dw 2
c4 dw 4
c6 dw 6
c5 dw 5
c15 dw 15
c7 dw 7
c8 dw 8
c10 dw 10
c136 dw 136
max db 64
len db ?
String db 64 dup (?)
sTemp db 64 dup(?)
dig dw ?
a dd ?
x dd ?
.386
.code
start:
mov ax, @data
mov ds, ax
lea dx, sEnterA
call InputFloat
fstp a
lea dx, sEnterX
call InputFloat
fstp x
lea dx, sY
mov ah, 9
int 21h
call CalcY
call float2str
lea dx, String
mov ah, 9
int 21h
mov ah, 0
int 16h
.exit 0
CalcY proc
fild C37
fidiv C2 ;ST = 37/2
fild C4
fimul C6 ;ST = 4*6, ST(1) = 37/2
fld x
fsub a ;ST = x - a, ST(1) = 4*6, ST(2) = 37/2
EXP ;ST = e^(x - a), ST(1) = 4*6, ST(2) = 37/2
fimul C5 ;ST = 5 * e^(x - a), ST(1) = 4*6, ST(2) = 37/2
faddp st(1) ;ST = 5 * e^(x - a) + 4*6, ST(1) = 37/2
fidiv C4 ;ST = (5 * e^(x - a) + 4*6)/4, ST(1) = 37/2
faddp ;ST = (5 * e^(x - a) + 4*6)/4 + 37/2
fild C15
fisub C7 ;ST = 15 - 7, ST(1) = (5 * e^(x - a) + 4*6)/4 + 37/2
fdivp ;ST = ((5 * e^(x - a) + 4*6)/4 + 37/2) / (15 - 7) = @ (чтобы меньше писать)
fld x ;ST = x, ST(1) = @
fsin ;ST = sin(x), ST(1) = @
fld a ;ST = a, ST(1) = sin(x), ST(2) = @
fcos ;ST = cos(a), ST(1) = sin(x), ST(2) = @
fdivp ;ST = sin(x)/cos(a), ST(1) = @
fimul C8 ;ST = 8*(sin(x)/cos(a)), ST(1) = @
fiadd C5 ;ST = 5 + 8*(sin(x)/cos(a)), ST(1) = @
fmulp st(1) ;ST = (5 + 8*(sin(x)/cos(a))) * @
fisub C136 ;ST = ((5 + 8*(sin(x)/cos(a))) * @) - 136
ret
CalcY endp
InputFloat proc
push dx
mov ah, 9
int 21h
lea dx, max
mov ah, 0ah
int 21h
lea si, String
call str2float
pushf
mov ah, 2
mov dl, 0dh
int 21h
mov dl, 0ah
int 21h
popf
pop dx
jc InputFloat
ret
InputFloat endp
str2float proc
fldz
xor dx, dx
xor bx, bx ;
xor di, di
s2fNext:
lodsb
cmp al, 0dh
je s2fSign
cmp al, '+'
jne s2f_minus
cmp bh, 0
jne s2f_err
test di, di
jne s2f_err
mov bh, 1
jmp s2fNext
s2f_minus:
cmp al, '-'
jne s2f_point
cmp bh, 0
jne s2f_err
test di, di
jne s2f_err
mov bx, 0101h
jmp s2fNext
s2f_point:
cmp al, '.'
jne s2f_digit
test dx, dx
jne s2f_err
jmp s2fInc
s2f_digit:
cmp al, '0'
jb s2f_err
cmp al, '9'
ja s2f_err
inc di
and ax, 0fh
mov dig, ax
test dx, dx
je s2fMul10
mov cx, dx
fild dig
s2fdiv:
fidiv c10
loop s2fdiv
faddp st(1)
s2fInc:
inc dx
jmp s2fNext
s2fMul10:
fimul c10
fiadd dig
jmp s2fNext
s2fSign:
cmp bl, 0
je s2fRet
fchs
s2fRet:
clc
ret
s2f_err:
stc
fstp st
ret
str2float endp
float2str proc
push es
push ds
pop es
lea di, sTemp
ftst
fstsw ax
sahf
jnz f2s_notZero
mov dx, 1
mov bl, 0
mov ax, '0'
stosw
jmp f2s_Ret
f2s_notZero:
mov al, ' '
jnc f2s_sign
mov al, '-'
fchs
f2s_sign:
stosb
fld1
fld st(1)
fprem
fsub st(2), st
fxch st(2)
xor cx, cx
f2s_2: fidiv c10
fxch st(1)
fld st(1)
fprem
fsub st(2), st
fimul c10
fistp dig
inc cx
push dig
fxch st(1)
ftst
fstsw ax
sahf
jnz f2s_2
f2s_3: pop ax
add al, 30h
stosb
loop f2s_3
fstp st(0)
fxch st(1)
ftst
fstsw ax
sahf
jz f2s_5
lea ax, sTemp
mov cx, di
sub cx, ax
sub cx, 63
neg cx
mov al, '.'
stosb
f2s_4: fimul c10
fxch st(1)
fld st(1)
fprem
fsub st(2), st
fxch st(2)
fistp dig
mov ax, dig
add al, 30h
stosb
fxch st(1)
ftst
fstsw ax
sahf
loopnz f2s_4
f2s_5: fstp st(0)
fstp st(0)
mov byte ptr [di], '$'
lea si, sTemp
lea di, String
mov dx, 0
f2s_6:
lodsb
stosb
inc dx
cmp dx, 14
je f2s_7
cmp al, '$'
jne f2s_6
dec dx
f2s_7:
mov byte ptr [di], '$'
f2s_Ret:
pop es
ret
float2str endp
end start[/code]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен