News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Quadratic Square Root Code Problem

Started by etow, January 30, 2008, 03:13:23 PM

Previous topic - Next topic

RuiLoureiro

Quote from: etow on February 05, 2008, 04:35:11 PM

Is there a function or procedure to read floating point numbers already in masm32 version 9 library?


             It is a good question. May be MichaelW ( or Greg, sorry Greg ) can answer. I dont know. I dont use any function or proc from masm (i used FpuFLtoA).
             But what do you mean with *** to read floating point numbers  *** ? A procedure you call and let you input only numbers (ascii codes) and +/- and code the result to the format REAL10 ? I dont know.
I think you should get the numbers as a string and then you should convert the string to the number. You should consider that we can type numbers like this: "-123 +45 -87" ! worst: " 123LLKK 1+2"

EDIT:

InputABC        proto :DWORD
.data
StringNumber    db 15 dup (0)           ; space, signal, 12 digits, last 0

.code
InputABC        proc  pABC:DWORD        ; this is a pointer to A_Number, etc.

@@:             ; 1 - Get the alphanumeric string to StringNumber
                ;     This string must be null terminated
               
                ; 2 - Convert StringNumber to REAL10 format
                ;     can use *** FpuAtoFL, lpSrc, lpDest, uID ***
                ;     If EAX=0 go backward to 1 or exit with error
               
                ret
InputABC        endp

          In this way, you use *** invoke InputABC, offset A_Number ***
          *** invoke InputABC, offset B_Number *** ...

RuiLoureiro

GregL

Quote from: etowIs there a function or procedure to read floating point numbers already in masm32 version 9 library?

There is the FpuAtoFL procedure in FPU.LIB.

etow

Hi RuiLoureiro,

What do you mean by:
Get the alphanumeric string to StringNumber
                ;     This string must be null terminated

Do you use mov Number_A, sval(input("Enter a real number for A : )) ?
Or something else?

Thanks

RuiLoureiro

#48
Quote from: etow on February 05, 2008, 11:10:16 PM
Do you use mov Number_A, sval(input("Enter a real number for A : )) ?
Or something else?

Hi etow,

           I dont know nothing about functions to input values in console applications
           functions like input, crt_sscanf, crt_sprintf, etc. etc. because i dont need to
           use them and i dont want to use them. I dont know where is the documentation, too.
           But you need, you should study them

           I dont like to use macros. I use it only in last cases. I dont know nothing
           about sval, real10$, etc. I dont need, i dont want to use them

           About your question, i think you wrote the procedure Input10 to get the
           alphanumeric string and to convert it to a REAL10 number. You should
           see if it works correctly. I dont Know.
           
Quote
           mov   Number_A, sval(input("Enter a real number for A : ))
           (I dont like to use instructions like this in my programs)
           AFAIK, sval is a macro that converts a string to a 32 bit integer. So,
           Number_A should be an integer.

           One more thing: you can use   ***fild     Mem32 *** where Mem32 is a 32 bit integer
                                   instead of   *** fld     Real10Value ***   

RuiLoureiro

GregL

etow,

The sval macro isn't going to work. What's wrong with InputR10? I wrote it and it works fine for me.


etow

Hi Greg,

I know that InputR10 works.  After you read in the real numbers, then should I save them to variables so that I could use them for later use in my program?

etow

Hi Greg,

Does your InputR10 reads the floating point or real numbers from the keyboard input from the console as real numbers or ASCII characters?


GregL

etow,

It uses the scanf function from the Microsoft C Run-Time Library. scanf reads ASCII from the standard input and converts it to a REAL8 (the Microsoft C Run-Time Library does not support REAL10 variables) and then converts that to a REAL10.

Alternatively, there is the StdIn procedure in masm32.lib that you could use to input a string and then use FpuAtoFL to convert the string to a REAL10. The functionality would be the same as with InputR10 except that it converts directly to a REAL10.


InputExt PROC pExt:PTR REAL10
    LOCAL szBuffer[64]:BYTE
    INVOKE RtlZeroMemory, ADDR szBuffer, SIZEOF szBuffer
    INVOKE StdIn, ADDR szBuffer, SIZEOF szBuffer
    INVOKE StripLF, ADDR szBuffer
    INVOKE FpuAtoFL, ADDR szBuffer, pExt, DEST_MEM
    ret
InputExt ENDP




etow

hi Greg and RuiLoureiro

here is my updated code below:
---------------------------------------------------------------------------------------------

.686 ; create 32 bit code
;The MASM32 Runtime Library include file.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\fpulib\fpu.inc
IncludeLib \masm32\fpulib\fpu.lib
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.Data
NumberA Real10 ?
NumberB Real10 ?
NumberC Real10 ?
Zero  Real10  0.0
NegativeOne Real10 - 1.0
One Real10 1.0
Two DT 2
NegativeFour DT - 4
negativeB Real10 ?
BSquared Real10 ?
temp_real Real10 ?
squareRootNumber Real10 ?
resultOfSquareRoot Real10 ?
negativeResultOfSquareRoot Real10 ?
numerator1 Real10 ?
numerator2 Real10 ?
denominator Real10 ?
xRoot1 Real10 ?
xRoot2 Real10 ?

.Code

start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    Call Main
    inkey        ; pause the screen while waiting for user to press any key
                   ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

InputR10 Proc pR10:Ptr Real10
    LOCAL r8:REAL8
    invoke crt_scanf, SADD("%lf"), ADDR r8
    mov eax, pR10
    finit
    fld r8
    fstp REAL10 PTR [eax]
    ret
InputR10 EndP

; ====================================
isgreater MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    true
    jbe   false
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM
; ====================================
isgreaterequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    jae   true
    jb    false
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
isless MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    jae   false
    jb    true
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
islessequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    false
    jbe   true
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
isnotequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    true
    jb    true
    jz    false
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
isequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    false
    jb    false
    jz    true
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
islessgreater MACRO r1:REQ, r2:REQ
    EXITM <isnotequal(r1, r2)>
ENDM
; ====================================
isapproxequal MACRO r1:REQ, r2:REQ, tolerance:REQ
    LOCAL diff
    .DATA?
        diff REAL10 ?
    .CODE   
    finit
    .IF isgreater(r1, r2)
        fld   r2
        fld   r1
    .ELSE
        fld   r1
        fld   r2
    .ENDIF   
    fsub
    fstp  diff
    fwait
    EXITM <islessequal(diff, tolerance)>
ENDM
; ====================================

printQuadraticFormat Proto:Real10, :Real10, :Real10
calculateQuadraticRoots Proto:Real10, :Real10, :Real10

Main Proc
  Local WantContinue:DWord
  Local counter:DWord
  ; WantContinue is a sentinel value for while loop
  ; NumberA is the X^2 coefficient of the quadratic equation
  ; NumberB is the X coefficient of the quadratic equation
  ; NumberC is the constant of the quadratic equation
  ; NumberA, NumberB, and NumberC are user's integer values entered

    Mov WantContinue, 0  ; set WantContinue = 0 to start while loop

    .While ((WantContinue >= 0) && (WantContinue < -1))
    ; while WantContinue greater than or equal to 0 And
    ; WantContinue less than -1
       print chr$(13, 10) ; a carriage return line feed will be outputted to the
                          ; screen
       print chr$("Quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
       print chr$("Enter a real number for A : ")
       Invoke InputR10, Addr NumberA
       print chr$("Enter a real number for B : ")
       Invoke InputR10, Addr NumberB
       print chr$("Enter a real number for C : ")
       Invoke InputR10, Addr NumberC

     .If isnotequal(NumberA, Zero) ; if NumberA != 0.0
       Invoke calculateQuadraticRoots, NumberA, NumberB, NumberC
       print chr$(13, 10)
     .ElseIf isequal(NumberA, Zero) ; if NumberA == 0.0
    print chr$(13, 10)
    print chr$("Error, Division by Zero!", 13, 10, 13, 10)
     .EndIf
       print chr$(13, 10)
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)

       Ffree St(0)
       Ffree St(1)
       Ffree St(2)
       Ffree St(3)
       Ffree St(4)
       Ffree St(5)
       Ffree St(6)
       Ffree St(7)

    .EndW
  Ret
Main EndP

printQuadraticFormat Proc A_Number:Real10, B_Number:Real10, C_Number:Real10

    .If isequal(A_Number, NegativeOne)
    ; if A_Number equals to -1.0
     print chr$("-1.0 X^2 ")
    .ElseIf isequal(A_Number, One)
     ; if A_Number equals to 1.0
       print chr$("1.0 X^2 ")
    .ElseIf (isgreater(A_Number, One) || isless(A_Number, NegativeOne))
     ; if A_Number greater than 1.0 Or A_Number less than - 1.0
       Invoke FpuFLtoA, 0, 4, Addr A_Number, SRC1_FPU Or SRC2_DIMM
       print chr$(" X^2 ")
    .EndIf

    .If isless(B_Number, NegativeOne)
    ; if B_Number less than -1.0
       Invoke FpuFLtoA, 0, 4, Addr B_Number, SRC1_FPU Or SRC2_DIMM
       print chr$(" X ")
    .ElseIf isequal(B_Number, NegativeOne)
    ; if B_Number equals to -1.0
       print chr$("-1.0 X ")
    .ElseIf isequal(B_Number, One)
    ; if B_Number equals to 1.0
       print chr$("+ 1.0 X ")
    .ElseIf isgreater(B_Number, One)
    ; if B_Number greater than 1.0
       print chr$("+ ")
       Invoke FpuFLtoA, 0, 4, Addr B_Number, SRC1_FPU Or SRC2_DIMM
       print chr$(" X ")
    .EndIf

    .If isless(C_Number, NegativeOne)
    ; if C_Number less than -1.0
       Invoke FpuFLtoA, 0, 4, Addr C_Number, SRC1_FPU Or SRC2_DIMM
    .ElseIf isequal(C_Number, NegativeOne)
    ; if C_Number equals to -1.0
       print chr$("-1.0 ")
    .ElseIf isgreater(C_Number, Zero)
    ; if C_Number greater than 0.0
       print chr$("+ ")
       Invoke FpuFLtoA, 0, 4, Addr C_Number, SRC1_FPU Or SRC2_DIMM
    .EndIf

Ret
printQuadraticFormat EndP

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   calculateQuadraticRoots procedure will calculate two real roots    <<
;<<   of a quadratic equation by receiving three coefficients from       <<
;<<   user as input                                                      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateQuadraticRoots Proc A_Number:Real10, B_Number:Real10, C_Number:Real10

  ; Quadratic Formula:  x = (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)

     Invoke FpuMul, Addr B_Number, Addr B_Number, Addr BSquared, SRC1_FPU Or SRC2_REAL Or DEST_FPU
     Invoke FpuMul, Addr NegativeFour, Addr A_Number, Addr temp_real, SRC1_FPU Or SRC2_REAL Or DEST_FPU
     Invoke FpuMul, Addr temp_real, Addr C_Number, Addr temp_real, SRC1_FPU Or SRC2_REAL Or DEST_FPU
     Invoke FpuAdd, Addr BSquared, Addr temp_real, Addr squareRootNumber, SRC1_REAL Or SRC2_DIMM

    .If isgreaterequal(squareRootNumber, Zero)

      Invoke FpuChs, Addr B_Number, Addr negativeB, SRC1_FPU
      Invoke FpuSqrt, Addr squareRootNumber, Addr resultOfSquareRoot, SRC1_DIMM Or DEST_FPU
      Invoke FpuAdd, Addr negativeB, Addr resultOfSquareRoot, Addr numerator1, SRC1_REAL Or SRC2_DIMM
      Invoke FpuChs, Addr resultOfSquareRoot, Addr negativeResultOfSquareRoot, SRC1_FPU
      Invoke FpuAdd, Addr negativeB, Addr negativeResultOfSquareRoot, Addr numerator2, SRC1_REAL Or SRC2_DIMM
      Invoke FpuMul, Addr Two, Addr A_Number, Addr denominator, SRC1_FPU Or SRC2_REAL Or DEST_FPU
      Invoke FpuDiv, Addr numerator1, Addr denominator, Addr xRoot1, SRC1_DIMM Or SRC2_DIMM
      Invoke FpuDiv, Addr numerator2, Addr denominator, Addr xRoot2, SRC1_DIMM Or SRC2_DIMM

      print chr$(13, 10)
      print chr$(" Solutions for quadratic equation : ")

      Invoke printQuadraticFormat, A_Number, B_Number, C_Number

      print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
                                 ; outputted to the screen
      print chr$(" X = ")
      print real10$ (xRoot1)   ; print signedRoot1 string array
      print chr$(13, 10)
      print chr$("  1 ", 13, 10)
      print chr$(" X = ")
      print real10$ (xRoot2)  ; print signedRoot2 string array
      print chr$(13, 10)
      print chr$("  2 ", 13, 10)
      print chr$(13, 10)

    .ElseIf islessequal(squareRootNumber, NegativeOne)
      ; if squareRootNumber less than or equal to -1.0
      print chr$(13, 10)
      print chr$("There are no real solutions for the quadratic equation : ")

      ; The following statement call output format procedure of the quadratic
      ; equation

      Invoke printQuadraticFormat, A_Number, B_Number, C_Number


      print chr$(" !", 13, 10, 13, 10) ; ! will be outputted along with two
                                       ; carriage return line feeds to the screen
    .EndIf
  Ret

calculateQuadraticRoots EndP

End start


------------------------------------------------------------------------------------------------

I have some problems with the code related to output results
The results are wrong and every time it show the same numbers again.

for example if I enter 1 for A , 0 for B, and -4 for C
the results are  x1 = 0.999995 and x2 = 0.999998

for example if I enter 1 for A, 0 for B, and -9 for C
the results are  x1 = 0.999995 and x2 = 0.999998

I am not sure what the results are like this?
Also the macros for isgreater, isequal, and etc.. do not work well.
I can not make them work properly.

Please help

Thanks


GregL

QuoteAlso the macros for isgreater, isequal, and etc.. do not work well.

What do you mean they don't work well? They have worked fine for me. You don't have to use them. In fact, if you really want to learn assembly language you would be better off not using them. Macros can simplify writing code but you need to understand how they work, otherwise they're just a crutch. I posted them so you (and others) could see the code and see how they work.

Take a look at the uID parameter for the Fpu* functions. You've got problems there.


RuiLoureiro

Hi etow,
         Let me say this (kindly),
         
         1. You have done a lot of work. But i think your prog is not well structured yet (IMO);
            But it is better, lighter

         2. Copy all macros to a new file, save it with MyMacros.inc,
            remove them form your prog, and add another include
            include   MyMacros.inc (a name you want);

         3. The error is here (i tested it, it is hard to follow):
Quote         
      Invoke FpuMul, Addr B_Number, Addr B_Number, Addr BSquared, SRC1_FPU Or SRC2_REAL Or DEST_FPU
      Invoke FpuMul, Addr NegativeFour, Addr A_Number, Addr temp_real, SRC1_FPU Or SRC2_REAL Or DEST_FPU
      Invoke FpuMul, Addr temp_real, Addr C_Number, Addr temp_real, SRC1_FPU Or SRC2_REAL Or DEST_FPU
      Invoke FpuAdd, Addr BSquared, Addr temp_real, Addr squareRootNumber, SRC1_REAL Or SRC2_DIMM

      Invoke FpuChs, Addr B_Number, Addr negativeB, SRC1_FPU
      Invoke FpuSqrt,Addr squareRootNumber, Addr resultOfSquareRoot, SRC1_DIMM Or DEST_FPU
      Invoke FpuAdd, Addr negativeB, Addr resultOfSquareRoot, Addr numerator1, SRC1_REAL Or SRC2_DIMM
      Invoke FpuChs, Addr resultOfSquareRoot, Addr negativeResultOfSquareRoot, SRC1_FPU
      Invoke FpuAdd, Addr negativeB, Addr negativeResultOfSquareRoot, Addr numerator2, SRC1_REAL Or SRC2_DIMM
      Invoke FpuMul, Addr Two, Addr A_Number, Addr denominator, SRC1_FPU Or SRC2_REAL Or DEST_FPU
      Invoke FpuDiv, Addr numerator1, Addr denominator, Addr xRoot1, SRC1_DIMM Or SRC2_DIMM
      Invoke FpuDiv, Addr numerator2, Addr denominator, Addr xRoot2, SRC1_DIMM Or SRC2_DIMM

 
            note: you call each one and you dont test if it returns with error or not.
                  you should control it.
                  This is why i said you should put that code in a separate procedure.

        4. If i am understanding english and math, you want to solve this problem:
           a) You have the equation
                                     a x^2  + b x + c = 0
                                     
           b) where a, b, c are integers                                     

           c) you want to get the real roots: x1=xRoot1 and x2= xRoot2.

           d) you want to show the equation and solutions
           
        5. The obvious is this: we need to input a, b, and c as integers
           So we need 3 integer variables, for instance, NumberA, NumberB, NumberC
           If we have something to test, we test this variables. It is easier.

        6. We decided for one method, it needs real numbers ANumber, BNumber, CNumber.
           Ok, we input integers to NumberA and convert it to ANumber, etc.
           You need to decide if you want to pass parameters or if you want
           to define them as global variables. With global, it is easier.
           We decided to use fpu directly. We dont need the variables ANumber,...
           and we dont need to convert them.

        7. If i have all things mixed, i have a lot of problems to test it.
           If i have a set of procedures, i can test each one, i can replace
           one for another without problems.
                   
Rui           

Sarel

So I messed up your program. :bg
Have a look and dump all those fpu library things except the string manipulation ones.
The FPU unit is quite tricky but just pay attention to what exactly the help file says of the op-codes. :U


;The MASM32 Runtime Library include file.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include   \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include   \masm32\fpulib\fpu.inc
IncludeLib   \masm32\fpulib\fpu.lib
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.Data
NumberA Real10 ?
NumberB Real10 ?
NumberC Real10 ?
Zero  Real10  0.0
NegativeOne Real10 - 1.0
One Real10 1.0
Two DT 2
NegativeFour DT - 4
negativeB Real10 ?
BSquared Real10 ?
temp_real Real10 ?
squareRootNumber Real10 ?
resultOfSquareRoot Real10 ?
negativeResultOfSquareRoot Real10 ?
numerator1 Real10 ?
numerator2 Real10 ?
denominator Real10 ?
xRoot1 Real10 ?
xRoot2 Real10 ?

.Code

start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    Call Main
    inkey        ; pause the screen while waiting for user to press any key
                   ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

InputR10 Proc pR10:Ptr Real10
    LOCAL r8:REAL8
    invoke crt_scanf, SADD("%lf"), ADDR r8
    mov eax, pR10
    finit
    fld r8
    fstp REAL10 PTR [eax]
    ret
InputR10 EndP
; ====================================
;Try this procedure instead of the macro (This is just an idea. it will how ever change you logic flow.)
;If r1 greater than r2 then eax is set to 1 (true) else it is set to 0
;Remember the proto statement and modify the other macro's to procedures.
;isgreater proto r1:Real10, r2:Real10

;isgreater proc r1:Real10, r2:Real10

;    finit
;    fld r2
;    fld r1
;    fcompp
;    fstsw ax
;    fwait      ;I dont know if this is needed.
;    sahf
;    jc r1_less_than_r2
;    mov eax,1
;    jmp @f
;  r1_less_than_r2:
;    xor eax,eax
;  @@:
;   ret
;endp


; ====================================
isgreater MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    true
    jbe   false
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM
; ====================================
isgreaterequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    jae   true
    jb    false
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
isless MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    jae   false
    jb    true
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
islessequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    false
    jbe   true
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
isnotequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    true
    jb    true
    jz    false
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
isequal MACRO r1:REQ, r2:REQ
    LOCAL error, true, false, clear
    finit
    fld r2
    fld r1
    fcom
    fstsw ax
    fwait
    sahf
    jpe   error
    ja    false
    jb    false
    jz    true
  error:
    mov eax, -1
    jmp clear
  true:
    mov eax, 1
    jmp clear
  false:
    xor eax, eax
  clear:
    fstp st(0)
    fstp st(0)
    EXITM <eax>
ENDM 
; ====================================
islessgreater MACRO r1:REQ, r2:REQ
    EXITM <isnotequal(r1, r2)>
ENDM
; ====================================
isapproxequal MACRO r1:REQ, r2:REQ, tolerance:REQ
    LOCAL diff
    .DATA?
        diff REAL10 ?
    .CODE   
    finit
    .IF isgreater(r1, r2)
        fld   r2
        fld   r1
    .ELSE
        fld   r1
        fld   r2
    .ENDIF   
    fsub
    fstp  diff
    fwait
    EXITM <islessequal(diff, tolerance)>
ENDM
; ====================================


printQuadraticFormat Proto:Real10, :Real10, :Real10
calculateQuadraticRoots Proto:Real10, :Real10, :Real10


Main Proc
  Local WantContinue:DWord
  Local counter:DWord
  ; WantContinue is a sentinel value for while loop
  ; NumberA is the X^2 coefficient of the quadratic equation
  ; NumberB is the X coefficient of the quadratic equation
  ; NumberC is the constant of the quadratic equation
  ; NumberA, NumberB, and NumberC are user's integer values entered

    Mov WantContinue, 0  ; set WantContinue = 0 to start while loop

    .While ((WantContinue >= 0) && (WantContinue < -1))
    ; while WantContinue greater than or equal to 0 And
    ; WantContinue less than -1
       print chr$(13, 10) ; a carriage return line feed will be outputted to the
                          ; screen
       print chr$("Quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
       print chr$("Enter a real number for A : ")
       Invoke InputR10, Addr NumberA
       print chr$("Enter a real number for B : ")
       Invoke InputR10, Addr NumberB
       print chr$("Enter a real number for C : ")
       Invoke InputR10, Addr NumberC

     .If isnotequal(NumberA, Zero) ; if NumberA != 0.0
       Invoke calculateQuadraticRoots, NumberA, NumberB, NumberC
       print chr$(13, 10)
     .ElseIf isequal(NumberA, Zero) ; if NumberA == 0.0
       print chr$(13, 10)
       print chr$("Error, Division by Zero!", 13, 10, 13, 10)
     .EndIf
       print chr$(13, 10)
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)

       Ffree St(0)
       Ffree St(1)
       Ffree St(2)
       Ffree St(3)
       Ffree St(4)
       Ffree St(5)
       Ffree St(6)
       Ffree St(7)

    .EndW
  Ret
Main EndP

printQuadraticFormat Proc A_Number:Real10, B_Number:Real10, C_Number:Real10

    .If isequal(A_Number, NegativeOne)
    ; if A_Number equals to -1.0
        print chr$("-1.0 X^2 ")
    .ElseIf isequal(A_Number, One)
     ; if A_Number equals to 1.0
       print chr$("1.0 X^2 ")
    .ElseIf (isgreater(A_Number, One) || isless(A_Number, NegativeOne))
     ; if A_Number greater than 1.0 Or A_Number less than - 1.0
       Invoke FpuFLtoA, 0, 4, Addr A_Number, SRC1_FPU Or SRC2_DIMM
       print chr$(" X^2 ")
    .EndIf

    .If isless(B_Number, NegativeOne)
    ; if B_Number less than -1.0
       Invoke FpuFLtoA, 0, 4, Addr B_Number, SRC1_FPU Or SRC2_DIMM
       print chr$(" X ")
    .ElseIf isequal(B_Number, NegativeOne)
    ; if B_Number equals to -1.0
       print chr$("-1.0 X ")
    .ElseIf isequal(B_Number, One)
      ; if B_Number equals to 1.0
       print chr$("+ 1.0 X ")
    .ElseIf isgreater(B_Number, One)
    ; if B_Number greater than 1.0
       print chr$("+ ")
       Invoke FpuFLtoA, 0, 4, Addr B_Number, SRC1_FPU Or SRC2_DIMM
       print chr$(" X ")
    .EndIf

    .If isless(C_Number, NegativeOne)
    ; if C_Number less than -1.0
       Invoke FpuFLtoA, 0, 4, Addr C_Number, SRC1_FPU Or SRC2_DIMM
    .ElseIf isequal(C_Number, NegativeOne)
    ; if C_Number equals to -1.0
       print chr$("-1.0 ")
    .ElseIf isgreater(C_Number, Zero)
    ; if C_Number greater than 0.0
       print chr$("+ ")
       Invoke FpuFLtoA, 0, 4, Addr C_Number, SRC1_FPU Or SRC2_DIMM
    .EndIf

   Ret
printQuadraticFormat EndP

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   calculateQuadraticRoots procedure will calculate two real roots    <<
;<<   of a quadratic equation by receiving three coefficients from       <<
;<<   user as input                                                      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateQuadraticRoots Proc A_Number:Real10, B_Number:Real10, C_Number:Real10

  ; Quadratic Formula:  x = (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)

  ;Square the value of B and store in BSquared
     finit
     fld B_Number
     fld st
     fmul ;st(0) holds the value B*B
     ;fstp BSquared
  ;Get 4*a*c The four is not a negative four it is ((b^2)-(4*a*c)) BE VERY CAREFULL
     fld1
     fld1
     fadd ;st(0) holds 2.0
     fld st
     fadd ;st(0) holds 4.0
     fld A_Number
     fld C_Number
     fmul
     fmul ;4*a*c is in st(0)       B^2 is in st(1)
  ;You need to subtract st(1) - ST(0)
     fsub ;This gives ((b^2)-(4*a*c)) in st(0)
  ;Compare with zero
     fldz
     fcomp st(1) ;((b^2)-(4*a*c)) again in st(0)
     fstsw ax
     sahf
     jc stZero_Less_Than_stOne ; Basicly the part under the root is greater or equal than zero
     jmp NegativeRootError


    ;.If isgreaterequal(squareRootNumber, Zero)
  stZero_Less_Than_stOne:
     fsqrt
     fld st ; make a coppy
     fld B_Number
     fchs
     fadd st(1),st
     fsubrp st(2),st ;st(0) is ((-b) + (the root)) and (st(1) is (-b) - (the root))
     fld A_Number
     fld1
     fld1
     fadd
     fmul ;st(0) holds 2*a
     fld st
     fdivp st(2),st
     fdivp st(2),st ;st(0) is (((-b) + (the root))/2a) and st(1) is (((-b) - (the root))/2a)
     fstp xRoot1
     fstp xRoot2


      print chr$(13, 10)
      print chr$(" Solutions for quadratic equation : ")

      Invoke printQuadraticFormat, A_Number, B_Number, C_Number

      print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
                                 ; outputted to the screen
      print chr$(" X = ")
      print real10$ (xRoot1)   ; print signedRoot1 string array
      print chr$(13, 10)
      print chr$("  1 ", 13, 10)
      print chr$(" X = ")
      print real10$ (xRoot2)  ; print signedRoot2 string array
      print chr$(13, 10)
      print chr$("  2 ", 13, 10)
      print chr$(13, 10)


      jmp OverAndOut


    ;.ElseIf islessequal(squareRootNumber, NegativeOne)
  NegativeRootError:
        ; if squareRootNumber less than or equal to -1.0
      print chr$(13, 10)
      print chr$("There are no real solutions for the quadratic equation : ")

      ; The following statement call output format procedure of the quadratic
      ; equation

      Invoke printQuadraticFormat, A_Number, B_Number, C_Number


      print chr$(" !", 13, 10, 13, 10) ; ! will be outputted along with two
                                       ; carriage return line feeds to the screen
    ;.EndIf

  OverAndOut:

  Ret

calculateQuadraticRoots EndP

End start

etow

Hi RuiLoureiro,
I have done what you told me to do.
Here is my updated code below:
-----------------------------------------------------------------------------------------------------------


.686 ; create 32 bit code
;The MASM32 Runtime Library include file.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\fpulib\fpu.inc
IncludeLib \masm32\fpulib\fpu.lib
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include MyMacros.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.Data

Zero  Real10  0.0         ; used to determine if there are real roots in the
                          ; quadratic formula
NegativeOne Real10 - 1.0  ; used in the comparision macros for print format
                          ; procedure
One Real10 1.0     ; used in comparision macros for print format procedure
NumberA Real10 ?   ; coefficient of X^2 in the quadratic equation
NumberB Real10 ?   ; coefficient of X in the quadratic equation
NumberC Real10 ?   ; constant in the quadratic equation
Two DD 2           ; number to use to get the denominator in the quadratic formula
NegativeFour DD - 4 ; number to use to get a square root number in the
                    ; quadratic formula
negativeB Real10 ? ; negating NumberB
BSquared Real10 ?  ; multiplying NumberB by itself
temp_real Real10 ? ; used as temporary variable to get part of the square root
                   ; number
squareRootNumber Real10 ? ; the square root number of the quadratic formula
resultOfSquareRoot Real10 ? ; the result of taking the square root of the number
                            ; in the quadratic formula
negativeResultOfSquareRoot Real10 ? ; negating the result of the square root answer
numerator1 Real10 ?   ; one numerator result of the quadratic formula
numerator2 Real10 ?   ; another numerator result of the quadratic formula
denominator Real10 ?  ; the denominator in the quadratic formula
xRoot1 Real10 ?    ;  one of the real number roots in the quadratic formula
xRoot2 Real10 ?    ;  second of the real number roots in the quadratic formula

.Code

start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    Call Main
    inkey        ; pause the screen while waiting for user to press any key
                   ; to continue
    exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   Input10 procedure will convert input   <<
;<<   from keyboard into real10 numbers      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

InputR10 Proc pR10:Ptr Real10
    LOCAL r8:REAL8
    invoke crt_scanf, SADD("%lf"), ADDR r8
    mov eax, pR10
    finit
    fld r8
    fstp REAL10 PTR [eax]
    ret
InputR10 EndP

printQuadraticFormat Proto:Real10, :Real10, :Real10
calculateQuadraticRoots Proto:Real10, :Real10, :Real10
calculateSquareRootNumber Proto:Real10, :Real10, :Real10
calculateXRoots Proto:Real10, :Real10

Main Proc
  Local WantContinue:DWord
  Local counter:DWord
  ; WantContinue is a sentinel value for while loop
  ; NumberA is the X^2 coefficient of the quadratic equation
  ; NumberB is the X coefficient of the quadratic equation
  ; NumberC is the constant of the quadratic equation
  ; NumberA, NumberB, and NumberC are user's integer values entered

    Mov WantContinue, 0  ; set WantContinue = 0 to start while loop

    .While ((WantContinue >= 0) && (WantContinue < -1))
    ; while WantContinue greater than or equal to 0 And
    ; WantContinue less than -1
       print chr$(13, 10) ; a carriage return line feed will be outputted to the
                          ; screen
       print chr$("Quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
       print chr$("Enter a real number for A : ")
       Invoke InputR10, Addr NumberA
       print chr$("Enter a real number for B : ")
       Invoke InputR10, Addr NumberB
       print chr$("Enter a real number for C : ")
       Invoke InputR10, Addr NumberC

     .If isnotequal(NumberA, Zero) ; if NumberA != 0.0
       Invoke calculateQuadraticRoots, NumberA, NumberB, NumberC
       print chr$(13, 10)
     .ElseIf isequal(NumberA, Zero) ; if NumberA == 0.0
    print chr$(13, 10)
    print chr$("Error, Division by Zero!", 13, 10, 13, 10)
     .EndIf
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)

    .EndW
  Ret
Main EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   printQuadraticFormat will output the quadratic equation entered by  <<
;<<   user to the screen                                                  <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

printQuadraticFormat Proc A_Number:Real10, B_Number:Real10, C_Number:Real10


    .If isequal(A_Number, NegativeOne)
    ; if A_Number equals to -1.0
     print chr$("-1.0 X^2 ")
    .ElseIf isequal(A_Number, One)
     ; if A_Number equals to 1.0
       print chr$("1.0 X^2 ")
    .ElseIf (isgreater(A_Number, One) || isless(A_Number, NegativeOne))
     ; if A_Number greater than 1.0 Or A_Number less than - 1.0
       Invoke FpuFLtoA, 0, 5, Addr A_Number, SRC1_FPU Or SRC2_DIMM
       print chr$(" X^2 ")
    .EndIf

    .If isless(B_Number, NegativeOne)
    ; if B_Number less than -1.0
       Invoke FpuFLtoA, 0, 5, Addr B_Number, SRC1_FPU Or SRC2_DIMM
       print chr$(" X ")
    .ElseIf isequal(B_Number, NegativeOne)
    ; if B_Number equals to -1.0
       print chr$("-1.0 X ")
    .ElseIf isequal(B_Number, One)
    ; if B_Number equals to 1.0
       print chr$("+ 1.0 X ")
    .ElseIf isgreater(B_Number, One)
    ; if B_Number greater than 1.0
       print chr$("+ ")
       Invoke FpuFLtoA, 0, 5, Addr B_Number, SRC1_FPU Or SRC2_DIMM
       print chr$(" X ")
    .EndIf

    .If isless(C_Number, NegativeOne)
    ; if C_Number less than -1.0
       Invoke FpuFLtoA, 0, 5, Addr C_Number, SRC1_FPU Or SRC2_DIMM
    .ElseIf isequal(C_Number, NegativeOne)
    ; if C_Number equals to -1.0
       print chr$("-1.0 ")
    .ElseIf isgreater(C_Number, Zero)
    ; if C_Number greater than 0.0
       print chr$("+ ")
       Invoke FpuFLtoA, 0, 5, Addr C_Number, SRC1_FPU Or SRC2_DIMM
    .EndIf

Ret
printQuadraticFormat EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  calculateSquareRootNumber procedure will calculate the square root number      <<
;<<  before taking its square root                                                  <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateSquareRootNumber Proc A_Number:Real10, B_Number:Real10, C_Number:Real10

     Invoke FpuMul, Addr B_Number, Addr B_Number, Addr BSquared, SRC1_FPU Or SRC2_FPU
     ; BSquared = B_Number * B_Number
     Invoke FpuMul, Addr NegativeFour, Addr A_Number, Addr temp_real, SRC1_FPU Or SRC2_FPU
     ; temp_real = NegativeFour * A_Number
     ; temp_real = -4.0 * A_Number
     Invoke FpuMul, Addr temp_real, Addr C_Number, Addr temp_real, SRC1_FPU Or SRC2_FPU
     ; temp_real = temp_real * C_Number
     ; temp_real = -4.0 * A_Number * C_Number
     Invoke FpuAdd, Addr BSquared, Addr temp_real, Addr squareRootNumber, SRC1_REAL Or SRC2_DIMM
     ; squareRootNumber = BSquared + temp_real
     ; squareRootNumber = B_Number * B_Number + -4.0 * A_Number * C_Number

Ret
calculateSquareRootNumber EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  calculateXRoots procedure will calculate the two real roots in the quadratic   <<
;<<  formula                                                                        <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateXRoots Proc A_Number:Real10, B_Number:Real10

      Invoke FpuChs, Addr B_Number, Addr negativeB, SRC1_FPU
      ; negativeB = -B_Number
      Invoke FpuSqrt, Addr squareRootNumber, Addr resultOfSquareRoot, SRC1_DIMM Or DEST_FPU
      ; resultOfSquareRoot = Sqrt(squareRootNumber)
      Invoke FpuAdd, Addr negativeB, Addr resultOfSquareRoot, Addr numerator1, SRC1_REAL Or SRC2_DIMM
      ; numerator1 = negativeB + resultOfSquareRoot = -B_Number + Sqrt(squareRootNumber)
      Invoke FpuChs, Addr resultOfSquareRoot, Addr negativeResultOfSquareRoot, SRC1_FPU
      ; negativeResultOfSquareRoot = -resultOfSquareRoot = -Sqrt(squareRootNumber)
      Invoke FpuAdd, Addr negativeB, Addr negativeResultOfSquareRoot, Addr numerator2, SRC1_REAL Or SRC2_DIMM
      ; numerator2 = negativeB + negativeResultOfSquareRoot
      ; numerator2 = -B_Number + -Sqrt(squareRootNumber)
      Invoke FpuMul, Addr Two, Addr A_Number, Addr denominator, SRC1_FPU Or SRC2_FPU
      ; denominator = Two * A_Number
      ; denominator = 2.0 * A_Number
      Invoke FpuDiv, Addr numerator1, Addr denominator, Addr xRoot1, SRC1_DIMM Or SRC2_DIMM
      ; xRoot1 = numerator1 / denominator
      ; xRoot1 = (-B_Number + Sqrt(squareRootNumber)) / (2.0 * A_Number)
      Invoke FpuDiv, Addr numerator2, Addr denominator, Addr xRoot2, SRC1_DIMM Or SRC2_DIMM
      ; xRoot2 = numerator2 / denominator
      ; xRoot2 = (-B_Number + -Sqrt(squareRootNumber)) / (2.0 * A_Number)

Ret
calculateXRoots EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   calculateQuadraticRoots procedure will calculate two real roots    <<
;<<   of a quadratic equation by receiving three coefficients from       <<
;<<   user as input and display the answers                              <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateQuadraticRoots Proc A_Number:Real10, B_Number:Real10, C_Number:Real10

     ; Quadratic Formula:  x = (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)
     ; where a, b, and c are real numbers And  a != 0

     Invoke calculateSquareRootNumber, A_Number, B_Number, C_Number

    .If isgreaterequal(squareRootNumber, Zero)

      Invoke calculateXRoots, A_Number, B_Number

      print chr$(13, 10)
      print chr$(" Solutions for quadratic equation : ")

      Invoke printQuadraticFormat, A_Number, B_Number, C_Number

      print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
                                 ; outputted to the screen
      print chr$(" X = ")
      print real10$ (xRoot1)   ; print the real number of one real root
                               ; in the quadratic formula
      print chr$(13, 10)
      print chr$("  1 ", 13, 10)
      print chr$(" X = ")
      print real10$ (xRoot2)  ; print the real number of another real root
                              ; in the quadratic formula
      print chr$(13, 10)
      print chr$("  2 ", 13, 10)
      print chr$(13, 10)

    .ElseIf isless(squareRootNumber, Zero)
      ; if squareRootNumber less than 0.0
      print chr$(13, 10)
      print chr$("There are no real solutions for the quadratic equation : ")

      ; The following statement call output format procedure of the quadratic
      ; equation

      Invoke printQuadraticFormat, A_Number, B_Number, C_Number

      print chr$(" !", 13, 10, 13, 10) ; ! will be outputted along with two
                                       ; carriage return line feeds to the screen
    .EndIf
  Ret

calculateQuadraticRoots EndP

End start


------------------------------------------------------------------------------------------

I am not sure which uIDs are correct for each FPU procedures

The uIDs are confusing to me.

Please help

Thanks

RuiLoureiro

#58
Hi etow,

Quote
The uIDs are confusing to me.

        1. I had the same problems with uIDs
       
        2. The A_Number, B_Number, C_Number, NumberA, NumberB, NumberC are confusing to me

        3. If you do this:
                            NumberA Real10 ?
                            print   chr$("Enter a real number for A : ")
                            Invoke  InputR10, Addr NumberA
           then
                            why  A_Number, B_Number, C_Number

           then
                            why this
                           
                            printQuadraticFormat Proto:Real10, :Real10, :Real10
                            calculateQuadraticRoots Proto:Real10, :Real10, :Real10
                            calculateSquareRootNumber Proto:Real10, :Real10, :Real10
                            calculateXRoots Proto:Real10, :Real10
                           
           when you can use
                            NumberA, NumberB, NumberC
                            and
                            printQuadraticFormat
                            calculateQuadraticRoots
                            calculateSquareRootNumber
                            calculateXRoots

           I am giving you just some ideas. I know you want write your code and learning
           i think. Am i wrong ?
           
           Where is the error now ?
..............................................
EDIT:
        Have o look at this example i did it quickly (p behind means pointer )

; File: Eq3.asm
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc

    Include         \masm32\fpulib\fpu.inc
    IncludeLib   \masm32\fpulib\fpu.lib

RealRoots       proto :DWORD,:DWORD,:DWORD   
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
;
; All numbers are real numbers
; ----------------------------
Number0         REAL10  0.0
Number2         REAL10  2.0
Number4         REAL10  4.0
Minus1          REAL10 -1.0
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
NumberA         Real10  1.0 ;1.0
NumberB         Real10  -2.0    ;0.0
NumberC         Real10  -4.0    ;4.0     ;-9.0
;------------------------------------
_RootX0         REAL10 ?
_RootX1         REAL10 ?
   
.data?
;_hInstance      dd ?
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.code
start:
            ;invoke  GetModuleHandle, 0             
            ;mov     _hInstance, eax            ;return value in eax=handle of program

            call    main
            invoke  ExitProcess, 0   
;...................................................
main        proc

            invoke  RealRoots, addr NumberA, addr NumberB, addr NumberC
            jc      _Emain

            cmp     eax, 2
            je      @F

            print   chr$("Real roots")
           
            print   chr$(13, 10)                           
            print   real10$ (_RootX0)
            print   chr$(13, 10)                       
           
            print   real10$ (_RootX1)
            ;
            print   chr$(13, 10)                       
            inkey
            ret
@@:           
            print chr$(" Complex roots ")                       
            inkey
            ret           
            ;
            ;  error
            ; ----------
_Emain:
            print chr$(" Error ")
            ;                       
            ; Stop and wait for a key
            ; -----------------------
            inkey
            ret
main        endp
; ########################################################
RealRoots       proc    pNumA:DWORD, pNumB:DWORD, pNumC:DWORD
                LOCAL   NumB2     :REAL10
                LOCAL   Num4AC    :REAL10
                LOCAL   NumB2_4AC :REAL10
                LOCAL   RootB2_4AC:REAL10
                LOCAL   Num2A     :REAL10

                LOCAL   SOLX0     :REAL10
                LOCAL   SOLX1     :REAL10               

                lea     ebx, NumB2
                invoke  FpuMul, pNumB, pNumB, ebx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         ; error -> exit
               
                lea     ecx, Num4AC
                invoke  FpuMul, pNumA, pNumC, ecx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots
                ;
                invoke  FpuMul, ecx, offset Number4, ecx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots

                lea     edx, NumB2_4AC
                invoke  FpuSub, ebx, ecx, edx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots
                ;
                ; Test if >= 0
                ; ------------
                invoke  FpuComp, edx, offset Number0, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots
                ;
                test    al, 00000100B
                jz      @F
                ;
                ; complex roots: NumB2_4AC < 0
                ; ---------------------------- 
                               
                mov     eax, 2
                clc
                ret
                ;
@@:             lea     ebx, RootB2_4AC
                invoke  FpuSqrt, edx, ebx, SRC1_REAL
                or      eax, eax
                jz      _rRealRoots

                lea     ecx, SOLX0                                     
                invoke  FpuSub, ebx, pNumB, ecx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         

                lea     edx, SOLX1                                     
                invoke  FpuAdd, ebx, pNumB, edx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         

                lea     ebx, Num2A
                invoke  FpuMul, pNumA, offset Number2, ebx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         
                               
                ; SOLX0
                invoke  FpuDiv, ecx, ebx, offset _RootX0, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         
               
                ; SOLX1
                invoke  FpuDiv, edx, ebx, edx, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         

                invoke  FpuMul, edx, offset Minus1, offset _RootX1, SRC1_REAL or SRC2_REAL
                or      eax, eax
                jz      _rRealRoots                                         
                ;
                mov     eax, 1               
                clc
                ret
                ;
                ; EAX = 0 => Error
                ;
_rRealRoots:   

                stc
                ret
RealRoots       endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end   start
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
Sarel,


;Get 4*a*c The four is not a negative four it is ((b^2)-(4*a*c)) BE VERY CAREFULL
     fld1
     fld1
     fadd ;st(0) holds 2.0
     fld st
     fadd ;st(0) holds 4.0
     fld A_Number
     fld C_Number
     fmul
     fmul     

         It isnt a good way to do this. This does what you want
         
     fld    A_Number
     fld    C_Number
     fmul                   ;  ac
     add    st(0), st(0)    ; 2ac
     add    st(0), st(0)    ; 4ac         


                           
Rui                           

Sarel

Hi etow

You should look at my posting earlier. I modified your "calculateQuadraticRoots" procedure. Copy the whole listing to the editor, assemble and link it. I think it is working now. There is a nice warning at the place where you made a mathmaticle error.

Have fun. :wink