Witam, mam problem z kodem pierwiastka 3 stopnia w assemblerze (z podanej liczny, z podana dokładnością). Czy ktoś mógłby pomóc znaleźć mi błąd?
(wykorzystuje wzór bodajże newtona-raphson, program do kompilacji to nasm oraz gcc, interfejs w c)
;uzywane wzory: przyblizenie = 2/3*poprzednie + x/3 *(1/poprzednie^2) - ze wzoru newtona-raphsona
;|
section .text use32
global _pier3
_pier3:
%idefine xx [ebp+8]
%idefine epsilon [ebp+12]
;ramka stosu
push ebp
mov ebp, esp
finit ; Initialize FPU
fld qword epsilon ; st(0)=epsilon
fld qword [root] ; st(0)=prevroot (Copy of root), st(1)=epsilon
fld qword [TwoThirds] ; st(0)=(2/3), st(1)=prevroot, st(2)=epsilon
fld qword xx ; st(0)=x, st(1)=(2/3), st(2)=prevroot, st(3)=epsilon
fdiv qword [Three] ; st(0)=(x/3), st(1)=(2/3), st(2)=prevroot, st(3)=epsilon
fld st2 ; st(0)=root, st(1)=(x/3), st(2)=(2/3), st(3)=prevroot, st(4)=epsilon
repeatAgain:
fld st0 ; st(0)=root, st(1)=root, st(2)=(x/3), st(3)=(2/3), st(4)=prevroot, st(5)=epsilon
fmul st0, st3 ; st(0)=(2/3*root), st(1)=root, st(2)=(x/3), st(3)=(2/3), st(4)=prevroot, st(5)=epsilon
fxch ; st(0)=root, st(1)=(2/3*root), st(2)=(x/3), st(3)=(2/3), st(4)=prevroot, st(5)=epsilon
fmul st0, st0 ; st(0)=(root*root), st(1)=(2/3*root), st(2)=(x/3), st(3)=(2/3), st(4)=prevroot, st(5)=epsilon
fdivr st0, st2 ; st(0)=((x/3)/(root*root)), st(1)=(2/3*root), st(2)=(x/3), st(3)=(2/3), st(4)=prevroot, st(5)=epsilon
faddp ; st(0)=((2/3*root)+(x/3)/(root*root)), st(1)=(x/3), st(2)=(2/3), st(3)=prevroot, st(4)=epsilon
fxch st3 ; st(0)=prevroot, st(1)=(x/3), st(2)=(2/3), newroot=st(3)=((2/3*root)+(x/3)/(root*root)), st(4)=epsilon
fsub st0, st3 ; st(0)=(prevroot-newroot), st(1)=(x/3), st(2)=(2/3), st(3)=newroot, st(4)=epsilon
fabs ; st(0)=(|prevroot-newroot|), st(1)=(x/3), st(2)=(2/3), st(3)=newroot, st(4)=epsilon
fld st4 ; st(0)=0.001, st(1)=(|prevroot-newroot|), st(2)=(x/3), st(3)=(2/3), st(4)=newroot, st(5)=epsilon
fcompp ; Do compare&set x87 flags pop top two values off stack
; st(0)=(x/3), st(1)=(2/3), st(2)=newroot, st(3)=epsilon
fstsw ax ; Copy x87 Status Word containing the result to AX
fwait ; Insure previous instruction completed
sahf ; Transfer condition codes to the CPU's flags register
fld st2 ; st(0)=newroot, st(1)=(x/3), st(2)=(2/3), st(3)=newroot, st(4)=epsilon
jbe repeatAgain ; If 0.001 <= (|oldroot-newroot|) repeat
; Remove temporary values on stack, cubed root in st(0)
ffree st4 ; st(0)=newroot, st(1)=(x/3), st(2)=(2/3), st(3)=epsilon
ffree st3 ; st(0)=newroot, st(1)=(x/3), st(2)=(2/3)
ffree st2 ; st(0)=newroot, st(1)=(x/3)
ffree st1 ; st(0)=newroot
leave
ret
section .data
root db 1.0
Three db 3.0
TwoThirds dq 0.6666666666666666