Linux nasm square root algorithm poblem

I am programming with the FPU under linux and the NASM assembler and linking using gcc

Here is the algorithm I am implementing:

take in x from the keyboard

 Initialize x_new = x
     x_old = x_new;
     x_new = (x_old + x / x_old) / 2;
   while |x_old - x_new|/x_new > e

I am having the problem with my compare and my conditional jump.
I have tested the values of the algorthm throughout and the values are correct to what I worked out on paper.
extern  printf
extern  scanf
global main
segment .data
prompt: db "Please enter a number: ",0
format: db "%lf", 0
output: db "%lf",10, 0
epsilon dq  0.0001
x2:     dq  2.0
segment .bss
x:      resq 1
x_new:  resq 1
x_old:   resq 1
x_temp:  resq 1
segment .text
        push prompt
        call printf
        add esp, 4
        push x
        push format
        call scanf
        add esp, 8
        fld qword [x]               ;fstack: x
        fstp qword [x_new]      ;fstack:
                                          ;x_new = x
.L1:    finit
        fld qword [x_new]       ;fstack: x_new
        fstp qword [x_old]       ;fstack:
                                         ;x_old = x_new
        finit                            ;clear the stack
                                         ;now lets make x_new = (x_old + (x/x_old))/2
        fld qword [x]              ;fstack: x
        fdivr qword [x_old]     ;fstack: x/x_old
        fadd qword [x_old]      ;fstack:(x_old + (x/x_old))
        fdiv qword [x2]           ;fstack:(x_old + (x/x_old))/2
        fstp qword [x_new]      ;fstack:
        finit                            ;clear the stack
                                          ;now lets make |x_old - x_new|/x_new
        fld qword [x_old]         ;fstack: x_old
        fsub qword [x_new]     ;fstack: x_old - x_new
        fabs                            ;fstack: |x_old - x_new|
        fdiv qword [x_new]      ;fstack: |x_old - x_new|/x_new
        fld qword [epsilon]     ;fstack: epsilon, |x_old - x_new|/x_new
        fcomi st1                       ;compare ST0 with ST1
        jl .L1
        push dword [x_new + 4]   ;outputting x_new after loop
        push dword [x_new]
        push output
        call printf
        add esp, 12

        mov eax, 0
Who is Participating?
joghurtConnect With a Mentor Commented:
Well, another approach. There were too many finit's even for the first sight so I've tried to reorganize the things a bit.

fld         qword ptr [x_new]
fstp        qword ptr [x_old]
fld         qword ptr [x]
fdiv        qword ptr [x_old]
fadd        qword ptr [x_old]
fdiv        qword ptr [x2]
fstp        qword ptr [x_new]
fld         qword ptr [x_old]
fsub        qword ptr [x_new]
fdiv        qword ptr [x_new]
fcomp       qword ptr [epsilon]
fnstsw      ax  
test        ah,41h
je          .L1

I haven't used fcomi because it won't run on older machines. (And because my development environment couldn't compile P6 instructions. :-)
But you can give it a try.
I believe you have a reason for not using FSQRT instead.

Well, by definition "jl" jumps if "SF <> OF".
However, fcomi sets the following flags: ZF, PF, CF.
So change jl to jc. Voila.
SaumZAuthor Commented:
I tried the jump with jc, and my code is still only doing one iteration. and outputting for example:

Please enter a number: 20

This number is correct, but only after one iteration.
this is the output that is at the bottom. of my code, where it outputs x_new

I also tested the number that I have from |x_old - x_new|/x_new
by putting it in a temp variable and outputting it and comparing to what I calculated using pencil and paper, and that is correct also.

Maybe the problem lies somewhere else? I am not sure at this point.

The reason for not just using fsqrt is that I am just learning the fpu programming, and I am trying to get myself used to programming in it by using different instructions with it.  

So, I may have logic errors someplace else in my code, but to me, it all looks correct.
"jnc", sorry.
SaumZAuthor Commented:
My whole problem in the task was a fdivr in place of a fdiv in my origional code...
I will give you the points, thank you for your help.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.