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

etow

Hi RuiLoureiro,
I got your etow11.zip file and compiled and it works.

Greg and RuiLoureiro, I know you use a macro you mentioned and test for NumberB.

I do not want to print 0.000000 if NumberB and/or NumberC is 0.
For example, if my equation is 1.000000 x^2 + 0.000000 x + 0.000000 = 0
For the 0 coefficient of x and constant 0.  I don't want to print these zeros.
The macro only prints a floating point up to a certain decimal precision.
Am I wrong with this answer?

GregL


RuiLoureiro

Hi etow,
            Copy the macro ext$ that Greg gave you before to the file ComparisonMacros.inc
             I think printQuadraticFormat does what you want. If you want test Inpu1.zip

printQuadraticFormat Proc

                     print chr$(" ")
                     print ext$(NumberA, 0, 5)
                     print chr$(" X^2 + ")
                     ;
       Invoke FpuComp, Addr NumberB, Offset Number0, SRC1_REAL Or SRC2_REAL
                     shr      al, 1                   ; mov bit 0 to Carry Flag
                     jc       NumberBIs0              ; NumberB = 0
   
                     print ext$(NumberB, 0, 5)                     
                     jmp      NextC
                     ;
NumberBIs0:          print ext$(NumberB, 0, 1)
NextC:               print chr$(" X + ")
                     ;
       Invoke FpuComp, Addr NumberC, Offset Number0, SRC1_REAL Or SRC2_REAL

                     shr      al, 1                   ; mov bit 0 to Carry Flag
                     jc       NumberCIs0              ; NumberC = 0

                     print     ext$(NumberC, 0, 5)
                     jmp       EndPrint
                     ;print chr$(" = 0 ", 13, 10)
                     ;Ret
                     ;
NumberCIs0:          print      ext$(NumberC, 0, 1)
EndPrint:            print      chr$(" = 0 ", 13, 10)
                     Ret
printQuadraticFormat EndP
RuiLoureiro

[attachment deleted by admin]

etow

Hi RuiLoureiro,

I am confused with the code in Input1.zip but I understand the function of it but how do I integrate it into my current code for the printQuadraticFormat?

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 ComparisonMacros.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateLinearRoot Proto :DWord,:DWord
InputR10            Proto :DWORD            ;Ptr Real10

.Data
Number0         Real10  0.0   ; used to determine if there are real roots in the
                              ; quadratic formula
Number2         Real10  2.0   ; number to use to get the denominator in the quadratic formula
Number1         Real10  1.0   ; number for comparison
Number4         Real10  4.0   ; number to get part of the square root number
Minus1          REAL10 -1.0
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
NumberA         Real10  ?     ; the coefficient of X^2 in the quadratic equation
NumberB         Real10  ?     ; the coefficient of X in the quadratic equation
NumberC         Real10  ?     ; the constant in the quadratic equation
;------------------------------------
_RootX0         Real10 ?      ; first real root solution to the quadratic formula
_RootX1         Real10 ?      ; second real root solution to the quadratic formula
_LinearRootX    Real10 ?      ; real linear root solution to the linear equation
; ##############################################################################################

; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.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:DWORD        ;Ptr Real10 the pointer to Real10 value is a DWORD value
    LOCAL r8:REAL8
    invoke crt_scanf, SADD("%lf"), ADDR r8
    mov eax, pR10
    finit
    fld r8
    fstp REAL10 PTR [eax]
    ret
InputR10 EndP
; ----------------------------------------------------------------------------------------------
Main Proc
  Local WantContinue:DWord
  ; WantContinue is a sentinel value for while loop

    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

       Invoke  FpuComp, Addr NumberA, Offset Number0, SRC1_REAL Or SRC2_REAL
       Or      Eax, Eax
       Jz      ErrorInComp
       ; ------------------------------------
       ; If bit 0 of EAX=1 => NumberA=Number0
       ; ------------------------------------
       shr      al, 1                   ; mov bit 0 to Carry Flag
       jc       linear                  ; NumberA = 0
       ;
       Call    calculateQuadraticRoots   ; no parameters its the same
                                         ; invoke calculateQuadraticRoots

       print   chr$(13, 10)
       Jmp     ToContinue
;.........................................
ErrorInComp:
        print   chr$(13, 10)
        print chr$(" Error comparing Number A against zero! ", 13, 10, 13, 10)
        jmp     ToContinue       
;..........................................
linear:
       Invoke FpuComp, Addr NumberB, Offset Number0, SRC1_REAL Or SRC2_REAL
       Or     Eax, Eax
       Jz     ZeroErrors
       ; ------------------------------------
       ; If bit 0 of EAX=1 => NumberB=Number0
       ; ------------------------------------
       shr      al, 1                   ; mov bit 0 to Carry Flag
       jc       ZeroErrors              ; NumberB = 0
       
        Invoke   calculateLinearRoot, Addr NumberB, Addr NumberC
        cmp      eax, 0
        jne      @F
        ;
        print   chr$(13, 10)
        print   chr$(" Error calculating linear roots", 13, 10)
        jmp     ToContinue

       ;
@@:    print chr$(13, 10)
       print chr$("Linear Equation : Bx + C ", 13, 10)
       print chr$(13, 10)
       print chr$(" Solution for linear equation : ", 13, 10)
       print chr$("-------------------------------", 13, 10)
       print chr$(" ")
       print real10$ (NumberB)

       Invoke FpuComp, Addr NumberC, Offset Number0, SRC1_REAL Or SRC2_REAL
       Shr Al, 1                  ; mov bit 0 to Carry Flag
       Jc NumberCIs0              ; NumberC = 0

       print chr$(" X + ")
       print ext$ (NumberC, 0, 5)
       Jmp Next

NumberCIs0:
   print chr$(" X ")
Next:
   print chr$(" = 0 ", 13, 10, 13, 10)
       print chr$(" X = ")
       print real10$ (_LinearRootX)
       print chr$(13, 10, 13, 10)
       print chr$(13, 10)
       Jmp ToContinue

ZeroErrors:
        print chr$(13, 10)
        print chr$(" Error, Numbers for A and B are zero! ", 13, 10, 13, 10)

ToContinue:
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)
       Invoke ClearScreen
    .EndW

  print chr$(13, 10)
  Ret
Main EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   printQuadraticFormat will output the quadratic equation entered by  <<
;<<   user to the screen                                                  <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

printQuadraticFormat Proc

                     print chr$(" ")
                     print ext$(NumberA, 0, 5)
                     print chr$(" X^2 ")
                     ;
       Invoke FpuComp, Addr NumberB, Offset Number0, SRC1_REAL Or SRC2_REAL
                     shr      al, 1                   ; mov bit 0 to Carry Flag
                     Jc NumberBIs0                    ; NumberB = 0

                     print chr$(" + ")
                     print ext$ (NumberB, 0, 5)
                     print chr$(" X ")
                     Jmp NextC
                     ;
NumberBIs0:
NextC:
                     ;
       Invoke FpuComp, Addr NumberC, Offset Number0, SRC1_REAL Or SRC2_REAL
                     Shr Al, 1                   ; mov bit 0 to Carry Flag
                     Jc NumberCIs0              ; NumberC = 0
                     print chr$(" + ")
                     print ext$ (NumberC, 0, 5)
                     jmp       EndPrint

NumberCIs0:
EndPrint:            print chr$(" = 0 ", 13, 10)
                     Ret
printQuadraticFormat EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  calculateLinearRoot procedure will calculate the root of the linear equation  <<
;<<  B x + C = 0  =>  x = - C / B
;<<  when NumberA is equal to 0 and NumberB is not equal to 0                      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateLinearRoot Proc  pNumB:DWord, pNumC:DWord
                    Local negativeNumC:Real10

     Lea    Edx, negativeNumC
     Invoke FpuChs, pNumC, Edx, SRC1_REAL                               ;Or SRC2_REAL
     cmp    eax, 0
     je     _rLinearRoot
     ;
     Invoke FpuDiv, Edx, pNumB, Offset _LinearRootX, SRC1_REAL Or SRC2_REAL
                    ; EAX= 0 -> error
_rLinearRoot:
Ret
calculateLinearRoot EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  calculateXRoots procedure will calculate the two real roots in the quadratic   <<
;<<  formula                                                                        <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateXRoots Proc pNumA:DWord, pNumB:DWord, pNumC:DWord

                ; pNumA is a pointer to NumA
                ; pNumB is a pointer to NumB
                ; pNumC is a pointer to NumC

                Local NumB2:Real10
                Local Num4AC:Real10
                Local NumB2_4AC:Real10
                Local RootB2_4AC:Real10
                Local Num2A:Real10
                ; NumB2 = NumberB * NumberB
                ; Num4AC = 4 * NumberA * NumberC
                ; NumB2_4AC = (NumberB * NumberB) - (4 * NumberA * NumberC)
                ; RootB2_4AC = sqrt(NumB2_4AC)
                ; Num2A = 2 * NumberA = denominator

                Local SOLX0:Real10
                Local SOLX1:Real10
                ; SOLX0 = first solution to quadratic formula
                ; SOLX1 = second solution to quadratic formula

                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 NumB2_4AC >= 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
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

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

      Invoke calculateXRoots, Addr NumberA, Addr NumberB, Addr NumberC
      Jc _ExitProc

      Cmp Eax, 2
      Je @F

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

      Invoke printQuadraticFormat

      print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
                                 ; outputted to the screen
      print chr$(" X = ")
      print real10$ (_RootX0)   ; print the real number of one real root
                                ; in the quadratic formula
      print chr$(13, 10)
      print chr$("  1 ", 13, 10, 13, 10)
      print chr$(" X = ")
      print real10$ (_RootX1)   ; 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)

      Ret                       ; exit here
      ;Jmp _ExitProc

@@:
      print chr$(13, 10)
      print chr$(" There are no real solutions for the quadratic equation : ", 13, 10)
      print chr$("---------------------------------------------------------", 13, 10)

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

      Invoke printQuadraticFormat

      print chr$(13, 10, " This equation has complex roots! ")
      print chr$(13, 10, 13, 10) ; two carriage return line feeds to the screen
      Ret                        ; exit here
;......................................................
_ExitProc:
        print chr$(13, 10)
        print chr$(" An Error occured while calculating the roots", 13, 10)
    Ret
calculateQuadraticRoots EndP
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
End     start
; ##############################################################################################




RuiLoureiro

#79
Hi etow,         
         Its quite easy if you understood Input1.
         
         1. You want to replace InputR10 by InputABC and you need
             OutputABC in printQuadraticFormat.
            So remove InputR10 and copy InputABC proc and OutputABC  proc
            and paste into your prog (for instance between
            ***calculateQuadraticRoots EndP*** and   ***End     start ***)

         2. ;InputR10    Proto :DWORD                  ; remove this                 
            InputABC     Proto :DWORD,:DWORD,:DWORD    ; add this 

         3. and add this into .DATA

_captionA       db "Input a", 0
_captionB       db "Input b", 0
_captionC       db "Input c", 0
_StringA        db 60 dup (?)
_StringB        db 60 dup (?)
_StringC        db 60 dup (?)
_hInstance      dd ?
_OutBuffer      db 180 dup (?)          ; buffer to handle the equation

        4. After  .start   add this
           ;*****************************
           invoke  GetModuleHandle, 0             
           mov     _hInstance, eax            ;return value in eax=handle of program
           ;*****************************
           because GetTextInput needs _hInstance
           
         5. Remove all ***Invoke InputR10*** and replace by
         ;***************************************************************
            invoke  InputABC, addr NumberA, addr _captionA, addr _StringA
            jc      InputError
            invoke  InputABC, addr NumberB, addr _captionB, addr _StringB
            jc      InputError
            invoke  InputABC, addr NumberC, addr _captionC, addr _StringC
            jc      InputError   
         ;***************************************************************
            and add (you can put it between ErrorInComp: and linear:
IputError:
            print   chr$(13, 10)
            print chr$(" Input Error ", 13, 10, 13, 10)
            jmp     ToContinue                     

         6.  replace printQuadraticFormat by           

printQuadraticFormat      proc
                    call    OutputABC
                    print   offset _OutBuffer
                    print   chr$(13, 10)                                           
                    ret
printQuadraticFormat       endp

         7. Make this correction in InputABC
; Action:
;           Gets the alphanumeric string that stands for a real number
;           Converts that string to a Real10 and put the result into the variable
;           pointed by pABC
         
          I think you can do all this stuff easily. But if you have problems...
          note: if you want to learn how to calculate the roots directly
                  see my post fpuFLtoA problem in Campus.
RuiLoureiro

etow

Hi RuiLoureiro,

My code updated with your code integrated into it.

Is there any way to change the output more?  The constant +C where C is an integer is two spaces more from the x in for Bx.  Is there a way to decrease the space between Bx and C by one space?

How do I output the format for the Linear Equation like the Quadratic Equation with no extra zeros?


;................................................
.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 ComparisonMacros.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateLinearRoot Proto :DWord,:DWord
InputR10            Proto :DWORD            ;Ptr Real10

.Data
Number0         Real10  0.0   ; used to determine if there are real roots in the
                              ; quadratic formula
Number2         Real10  2.0   ; number to use to get the denominator in the quadratic formula
Number1         Real10  1.0   ; number for comparison
Number4         Real10  4.0   ; number to get part of the square root number
Minus1          REAL10 -1.0
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
NumberA         Real10  ?     ; the coefficient of X^2 in the quadratic equation
NumberB         Real10  ?     ; the coefficient of X in the quadratic equation
NumberC         Real10  ?     ; the constant in the quadratic equation
;------------------------------------
_RootX0         Real10 ?      ; first real root solution to the quadratic formula
_RootX1         Real10 ?      ; second real root solution to the quadratic formula
_LinearRootX    Real10 ?      ; real linear root solution to the linear equation
_captionA       DB "Input A", 0
_captionB       DB "Input B", 0
_captionC       DB "Input C", 0
_StringA        DB 60 dup (?)
_StringB        DB 60 dup (?)
_StringC        DB 60 dup (?)
_hInstance      DD ?
_OutBuffer      DB 180 dup (?)          ; buffer to handle the equation
; ##############################################################################################

; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.Code

start:
;*****************************
    Invoke  GetModuleHandle, 0
    Mov _hInstance, Eax            ;return value in eax=handle of program
;*****************************

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

InputABC Proto:DWord, :DWord, :DWord

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

InputABC        proc    pABC:DWORD, pCaption:DWORD, pBuf:DWORD
                LOCAL   Buffer[60]:BYTE
                ;
                push    esi
                push    edi
                ;
                lea     esi, Buffer               
                invoke  GetTextInput, NULL, _hInstance, NULL, pCaption,
                                      NULL, esi
                cmp     eax, 1
                je      _eInputABC                      ; exit                             
                ;
                mov     edi, pBuf                                                             
                xor     ecx, ecx        ; number of digits + 1 sign + 1
                ;
                Xor Edx, Edx
_iInputABC:     movzx   eax, byte ptr [esi + edx]
                inc     edx
                ;
                Cmp Al, 0
                Je _aInputABC
                ;               
                Cmp Al, 20H
                Je _iInputABC              ; space
                ;               
                Cmp Al, 9H
                Je _iInputABC              ; tab
                ;
                Cmp Al, "-"
                Je _nInputABC0
                ;                             
                Cmp Al, "+"
                Je _nInputABC0
                ;
                Cmp Al, "."
                Je _nInputABC0
                ;               
                Cmp Al, "0"
                Jb _eInputABC
                ;
                Cmp Al, "9"
                Ja _eInputABC
                ;
                Mov Byte Ptr [Edi + Ecx], "+"           ; begin with +
                inc     ecx
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
_nInputABC0:    mov     byte ptr [edi + ecx], al
                inc     ecx
                ;
_nInputABC:     movzx   eax, byte ptr [esi + edx]
                inc     edx
                ;
                cmp     al, 0
                je      _aInputABC
                ;               
                cmp     al, 20h
                je      _nInputABC
                ;               
                cmp     al, 9h
                je      _nInputABC                               
                ;
                cmp     al, "."
                je     _nInputABC0
                ;                               
                cmp     al, "0"
                jb      _eInputABC
                ;
                cmp     al, "9"
                jbe      _nInputABC0                               
                ja      _eInputABC
                ;     
_aInputABC:     cmp     ecx, 0
                je      _eInputABC                  ; reject
                ;
                cmp     ecx, 12
                ja      _eInputABC                  ; more than 10 digits
                ;
                ; convert
                ; ------- 
                mov     byte ptr [edi + ecx], 0     ; end with 0
                ;
                mov     edx, pABC               
                invoke  FpuAtoFL, edi, edx, DEST_MEM
                or      eax, eax
                jz      _eInputABC                  ; error
                ;
                clc
                pop     edi
                pop     esi
                ret
                ;
_eInputABC:     stc
                pop     edi
                pop     esi
                ret
InputABC EndP
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
OutputABC       proc
                push    edi
                ;
                cld
                mov     edi, offset _OutBuffer
                mov     edx, offset _StringA
                ;
@@:             movzx   eax, byte ptr [edx]
                inc     edx
                cmp     al, 0
                je      @F
                ;
                stosb
                jne     @B
               
@@:             mov     eax, "2^X "
                stosd
                ;
                Mov Al, " "
                stosb
                ;
                mov     edx, offset _StringB
                ;
@@:             movzx   eax, byte ptr [edx]
                inc     edx
                cmp     al, 0
                je      @F
                ;
                stosb
                jne     @B
               
@@:             mov     eax, "  X "
                stosd
                ;
                mov     edx, offset _StringC
                ;
@@:             movzx   eax, byte ptr [edx]
                inc     edx
                cmp     al, 0
                je      @F
                ;
                stosb
                jmp     @B
               
@@:             mov     eax, " 0= "
                stosd
                mov     byte ptr [edi], 0       ; end with 0                             
                ;
                pop     edi
                ret
OutputABC EndP

; ----------------------------------------------------------------------------------------------
Main Proc
  Local WantContinue:DWord
  ; WantContinue is a sentinel value for while loop

    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)
       Invoke  InputABC, Addr NumberA, Addr _captionA, Addr _StringA
       Jc InputError
       Invoke  InputABC, Addr NumberB, Addr _captionB, Addr _StringB
       Jc InputError
       Invoke  InputABC, Addr NumberC, Addr _captionC, Addr _StringC
       Jc InputError

       Invoke  FpuComp, Addr NumberA, Offset Number0, SRC1_REAL Or SRC2_REAL
       Or      Eax, Eax
       Jz      ErrorInComp
       ; ------------------------------------
       ; If bit 0 of EAX=1 => NumberA=Number0
       ; ------------------------------------
       shr      al, 1                   ; mov bit 0 to Carry Flag
       jc       linear                  ; NumberA = 0
       ;
       Call    calculateQuadraticRoots   ; no parameters its the same
                                         ; invoke calculateQuadraticRoots

       print   chr$(13, 10)
       Jmp     ToContinue
;.........................................
ErrorInComp:
        print   chr$(13, 10)
        print chr$(" Error comparing Number A against zero! ", 13, 10, 13, 10)
        jmp     ToContinue       
;..........................................
InputError:
            print   chr$(13, 10)
            print chr$(" Input Error ", 13, 10, 13, 10)
            jmp     ToContinue                     
;..........................................
linear:
       Invoke FpuComp, Addr NumberB, Offset Number0, SRC1_REAL Or SRC2_REAL
       Or     Eax, Eax
       Jz     ZeroErrors
       ; ------------------------------------
       ; If bit 0 of EAX=1 => NumberB=Number0
       ; ------------------------------------
       shr      al, 1                   ; mov bit 0 to Carry Flag
       jc       ZeroErrors              ; NumberB = 0
       
        Invoke   calculateLinearRoot, Addr NumberB, Addr NumberC
        cmp      eax, 0
        jne      @F
        ;
        print   chr$(13, 10)
        print   chr$(" Error calculating linear roots", 13, 10)
        jmp     ToContinue

       ;
@@:    print chr$(13, 10)
       print chr$("linear Equation : Bx + C ", 13, 10)
       print chr$(13, 10)
       print chr$(" Solution for linear equation : ", 13, 10)
       print chr$("-------------------------------", 13, 10)
       print chr$(" ")
       print real10$ (NumberB)

       Invoke FpuComp, Addr NumberC, Offset Number0, SRC1_REAL Or SRC2_REAL
       Shr Al, 1                  ; mov bit 0 to Carry Flag
       Jc NumberCIs0              ; NumberC = 0

       print chr$(" X + ")
       print ext$ (NumberC, 0, 5)
       Jmp Next

NumberCIs0:
   print chr$(" X ")
Next:
   print chr$(" = 0 ", 13, 10, 13, 10)
       print chr$(" X = ")
       print real10$ (_LinearRootX)
       print chr$(13, 10, 13, 10)
       print chr$(13, 10)
       Jmp ToContinue

ZeroErrors:
        print chr$(13, 10)
        print chr$(" Error, Numbers for A and B are zero! ", 13, 10, 13, 10)

ToContinue:
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)
       Invoke ClearScreen
    .EndW

  print chr$(13, 10)
  Ret
Main EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   printQuadraticFormat will output the quadratic equation entered by  <<
;<<   user to the screen                                                  <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

printQuadraticFormat      proc
                    Call OutputABC
                    print chr$(" ")
                    print   offset _OutBuffer
                    print   chr$(13, 10)                                           
                    ret
printQuadraticFormat       endp
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  calculateLinearRoot procedure will calculate the root of the linear equation  <<
;<<  B x + C = 0  =>  x = - C / B
;<<  when NumberA is equal to 0 and NumberB is not equal to 0                      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateLinearRoot Proc  pNumB:DWord, pNumC:DWord
                    Local negativeNumC:Real10

     Lea    Edx, negativeNumC
     Invoke FpuChs, pNumC, Edx, SRC1_REAL                               ;Or SRC2_REAL
     cmp    eax, 0
     je     _rLinearRoot
     ;
     Invoke FpuDiv, Edx, pNumB, Offset _LinearRootX, SRC1_REAL Or SRC2_REAL
                    ; EAX= 0 -> error
_rLinearRoot:
Ret
calculateLinearRoot EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  calculateXRoots procedure will calculate the two real roots in the quadratic   <<
;<<  formula                                                                        <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateXRoots Proc pNumA:DWord, pNumB:DWord, pNumC:DWord

                ; pNumA is a pointer to NumA
                ; pNumB is a pointer to NumB
                ; pNumC is a pointer to NumC

                Local NumB2:Real10
                Local Num4AC:Real10
                Local NumB2_4AC:Real10
                Local RootB2_4AC:Real10
                Local Num2A:Real10
                ; NumB2 = NumberB * NumberB
                ; Num4AC = 4 * NumberA * NumberC
                ; NumB2_4AC = (NumberB * NumberB) - (4 * NumberA * NumberC)
                ; RootB2_4AC = sqrt(NumB2_4AC)
                ; Num2A = 2 * NumberA = denominator

                Local SOLX0:Real10
                Local SOLX1:Real10
                ; SOLX0 = first solution to quadratic formula
                ; SOLX1 = second solution to quadratic formula

                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 NumB2_4AC >= 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
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

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

      Invoke calculateXRoots, Addr NumberA, Addr NumberB, Addr NumberC
      Jc _ExitProc

      Cmp Eax, 2
      Je @F

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

      Invoke printQuadraticFormat

      print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
                                 ; outputted to the screen
      print chr$(" X = ")
      print real10$ (_RootX0)   ; print the real number of one real root
                                ; in the quadratic formula
      print chr$(13, 10)
      print chr$("  1 ", 13, 10, 13, 10)
      print chr$(" X = ")
      print real10$ (_RootX1)   ; 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)

      Ret                       ; exit here
      ;Jmp _ExitProc

@@:
      print chr$(13, 10)
      print chr$(" There are no real solutions for the quadratic equation : ", 13, 10)
      print chr$("---------------------------------------------------------", 13, 10)

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

      Invoke printQuadraticFormat

      print chr$(13, 10, " This equation has complex roots! ")
      print chr$(13, 10, 13, 10) ; two carriage return line feeds to the screen
      Ret                        ; exit here
;......................................................
_ExitProc:
        print chr$(13, 10)
        print chr$(" An Error occured while calculating the roots", 13, 10)
    Ret
calculateQuadraticRoots EndP
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
End     start
; ##############################################################################################

RuiLoureiro

Hi etow,         
         Its quite easy if you understood OutputABC. Read it and try to understand how
         it works. Repace printQuadraticFormat name by printEquation and use
         it to print b X + c = 0 also. Define a flag _FlgEqType. When you call
         a quadratic equation, put _FlgEqType=1; when you call a linear equation
         put _FlgEqType=0. Then inside OutputABC, use _FlgEqType to get
         a x^2 + b x + c = 0 or only b x + c = 0 to _OutBuffer.
         Another thing: we dont need to define another variable _LinearRootX.
                        We can use _RootX0. Its more simple
         I think it is better to put InputABC and OutputABC at the bottom, not
         at the top. When we want to follow the program we begin at «start:» and
         we begin to see it first. To end the program it is better to use 1
         instead of -1. We dont need to type 2 things. Return-> continues; 1=Quit.
         You can consider to improve printEquation in such a way that it prints
         the roots also.
         
RuiLoureiro         


[attachment deleted by admin]

etow

Hi RuiLoureiro,
I don't see the printEquation file in the zip file


RuiLoureiro

Quote from: etow on February 13, 2008, 05:32:04 PM
I don't see the printEquation file in the zip file
here (its not a file but a proc):
       ; ******************
       ;        Exit
       ; ******************
            print    chr$(13, 10)
            inkey           ; pause the screen while waiting for user to press any key
                            ; to continue
            invoke    ExitProcess, 0                   ; exit from program
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   printEquation will output the quadratic equation entered by user    <<
;<<   to the screen                                                       <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
printEquation       proc
RuiLoureiro

etow

Hi RuiLoureiro,

I have some questions for you.

What does the "cld" do?  What does the instructions "stosb" and "stosd" do?
What does "je @F"  jump to ?   What does "jne @B" jump to ?"  What does byte ptr[edi] mean?
What does "movzx eax, byte ptr [edx] "mean?

Thanks

RuiLoureiro

Quote from: etow on February 13, 2008, 11:19:01 PM
What does the "cld" do?  What does the instructions "stosb" and "stosd" do?
What does "je @F"  jump to ?   What does "jne @B" jump to ?"  What does byte ptr[edi] mean?
What does "movzx eax, byte ptr [edx] "mean?

Hi etow,
             Try to understand this example: You define a variable in .DATA section
             for 30 bytes. For instance:   _ThisVariable      DB 30 dup (?)
             Whats the address of that variable ? Simply offset _ThisVariable. To put
             that address in the register EDI: mov      edi, offset _ThisVariable.
             Now you want to put bytes begining at the address EDI up to 30 bytes.
             
            1. stosb   means store single byte and moves the byte in AL to the address
                       which is in register EDI and, at the end, the register EDI
                       is incremented (if DF is 0) or decremented (if DF is 1).
                       DF means Direction Flag.
                       If you want to go from lower addresses to higher,
                       you must put DF to 0. We do this with the
                       instruction CLD (Clear Direction). If you want to go from higher
                       addresses to lower, you must put DF to 1. We do this with the
                       instruction STD (Set Direction). Generally we use CLD to
                       go from top to bottom

                stosd   stores the value in EAX. At the end EDI=EDI+4 if DF=0 and...

            Now think about this case: mov   edi, offset _ThisVariable
                                       add   edi, 29
            Where are we ? If you want to go to the top, to the address offset _ThisVariable,
            using instructios stosb or stosd, we need to do STD before. Yes ?
                                       
            2. About "@F" and "@B" and labels @@:
               Look at this 2 examples

; this case i use labels _previous and _next
_previous:      mov     al, byte ptr [esi]      ; move the byte at the address ESI to AL
                cmp     al, 0
                je      _next     
                ...
                inc     esi
                jmp     _previous
_next:          ...


; this case i use labels @@ and "@F" and "@B"
@@:             mov     al, byte ptr [esi]  ; move the byte at the address ESI to AL
                cmp     al, 0
                je      @F                  ; label @@ forward
                ...
                inc     esi
                jmp     @B  ; jump to the label @@ backward, defined before this point here
@@:             ...

            3. byte ptr [edi], byte ptr[edx] means the byte which is in the address EDI, EDX
            4. movzx    eax, byte ptr [edx] means move the byte which is in the address EDX
               to AL and complete the register eax with zeros. If the byte at the address
               EDX is 30h, at the end, the four bytes in eax are EAX= 00 00 00 30h
                                                                                                      AH AL
            You need to get a manual. All this stuff is there.
             I hope this help you
RuiLoureiro

etow

Hi RuiLoureiro,  I understand your explanation and try to modify my code.
I commented where I modify the code to try to shrink the space between the X term and the constant but could not get it to work.

Please give me some hints.
-------------------------------------------------------------------------------------------------


;................................................
.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 ComparisonMacros.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateLinearRoot Proto :DWord, :DWord
InputABC Proto:DWord, :DWord, :DWord

.Data
Number0         Real10  0.0   ; used to determine if there are real roots in the
                              ; quadratic formula
Number2         Real10  2.0   ; number to use to get the denominator in the quadratic formula
Number1         Real10  1.0   ; number for comparison
Number4         Real10  4.0   ; number to get part of the square root number
Minus1          Real10 - 1.0   ; used for negation
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
NumberA         Real10  ?     ; the coefficient of X^2 in the quadratic equation
NumberB         Real10  ?     ; the coefficient of X in the quadratic equation
NumberC         Real10  ?     ; the constant in the quadratic equation
;------------------------------------
_RootX0         Real10 ?      ; first real root solution to the quadratic formula
_RootX1         Real10 ?      ; second real root solution to the quadratic formula
_LinearRootX    Real10 ?      ; real linear root solution to the linear equation
_captionA       DB "Input A", 0  ; input windows box for the coefficient of X^2
                                 ; of quadratic equation
_captionB       DB "Input B", 0  ; input windows box for the coefficient of X
                                 ; of quadratic equation
_captionC       DB "Input C", 0  ; input windows box for the constant
                                 ; of quadratic equation
_StringA        DB 60 Dup (?) ; output string for the input for coefficient X^2
                              ; quadratic equation concatenate with X^2
_StringB        DB 60 Dup (?) ; output string for the input for coefficient X
                              ; quadratic equation along concatenate with X
_StringC        DB 60 Dup (?) ; output string for the input for constant
                              ; quadratic equation
_hInstance      DD ?
_OutBuffer      DB 180 Dup (?)  ; buffer to handle the equation
; ##############################################################################################

; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.Code

start:
;*******************************
    Invoke  GetModuleHandle, 0
    Mov _hInstance, Eax            ;return value in eax=handle of program
;*******************************

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

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   InputABC procedure will convert input from keyboard   <<<
;<<   using windows boxes into real10 numbers               <<<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

InputABC        proc    pABC:DWORD, pCaption:DWORD, pBuf:DWORD
                Local Buffer[64]:Byte
                ;
                push    esi
                push    edi
                ;
                Lea Esi, Buffer  ; Esi is the pointer address of Buffer
                invoke  GetTextInput, NULL, _hInstance, NULL, pCaption,
                                      NULL, esi
                Cmp Eax, 1   ; compare Eax with 1
                je      _eInputABC                      ; exit                             
                ;
                mov     edi, pBuf                                                             
                xor     ecx, ecx        ; number of digits + 1 sign + 1
                ;
                Xor Edx, Edx
_iInputABC:     movzx   eax, byte ptr [esi + edx]
                Inc Edx      ; edx = edx + 1
                ;
                Cmp Al, 0         ; compare Al with 0
                Je _aInputABC
                ;               
                Cmp Al, 20H      ; compare Al with 20H
                Je _iInputABC              ; space
                ;               
                Cmp Al, 9H      ; compare Al with 9H
                Je _iInputABC              ; tab
                ;
                Cmp Al, "-"     ; compare Al with character "-"
                Je _nInputABC0
                ;                             
                Cmp Al, "+"    ; compare Al with character "+"
                Je _nInputABC0
                ;
                Cmp Al, "."    ; compare Al with character "."
                Je _nInputABC0
                ;               
                Cmp Al, "0"    ; compare Al with character "0"
                Jb _eInputABC
                ;
                Cmp Al, "9"    ; compare Al with character "9"
                Ja _eInputABC
                ;
                Mov Byte Ptr [Edi + Ecx], "+"           ; begin with +
                Inc Ecx    ;  ecx = ecx + 1
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
_nInputABC0:    mov     byte ptr [edi + ecx], al
                Inc Ecx  ; ecx = ecx + 1
                ;
_nInputABC:     movzx   eax, byte ptr [esi + edx]
                Inc Edx  ; edx = edx + 1
                ;
                Cmp Al, 0   ; compare Al with 0
                je      _aInputABC
                ;               
                Cmp Al, 20H     ; compare Al with 20h
                je      _nInputABC
                ;               
                Cmp Al, 9H  ; compare Al with 9h
                je      _nInputABC                               
                ;
                Cmp Al, "."     ; compare Al with character "."
                je     _nInputABC0
                ;                               
                Cmp Al, "0"     ; compare Al with character "0"
                jb      _eInputABC
                ;
                Cmp Al, "9"  ; compare Al with character "9"
                jbe      _nInputABC0                               
                ja      _eInputABC
                ;     
_aInputABC:     Cmp Ecx, 0 ; compare Ecx with 0
                je      _eInputABC                  ; reject
                ;
                Cmp Ecx, 12  ; compare Ecx with 12
                ja      _eInputABC                  ; more than 10 digits
                ;
                ; convert
                ; ------- 
                mov     byte ptr [edi + ecx], 0     ; end with 0
                ;
                mov     edx, pABC               
                invoke  FpuAtoFL, edi, edx, DEST_MEM
                Or Eax, Eax  ; activate zero flag
                jz      _eInputABC                  ; error
                ;
                clc
                pop     edi
                pop     esi
                ret
                ;
_eInputABC:     stc
                pop     edi
                pop     esi
                ret
InputABC EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  OutputABC procedure will output the format of the user's quadratic equation  <<
;<<  without the extra zeros                                                      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

OutputABC       proc
                push    edi
                ;
                cld
                mov     edi, offset _OutBuffer
                mov     edx, offset _StringA
                ;
@@:             movzx   eax, byte ptr [edx]
                inc     edx
                cmp     al, 0
                je      @F
                ;
                stosb
                jne     @B
               
@@:             Mov Eax, "2^X "
                stosd
                ;
                Mov Al, " "
                Stosb
                ;
                mov     edx, offset _StringB
                ;
@@:             movzx   eax, byte ptr [edx]
                inc     edx
                cmp     al, 0
                je      @F
                ;
                stosb
                Jne @B
               
@@:             Mov Eax, "  X "
                Stosd
                ;
                Cld          ; try to shrink the space between the X term and constant
                Sub Edx, 1   ; try to shrink the space between the X term and constant
                Mov Edx, Offset _StringC
                ;
@@:             Movzx Eax, Byte Ptr [Edx]
                Inc Edx
                cmp     al, 0
                je      @F
                ;
                Stosb
                jmp     @B
               
@@:             Mov Eax, "0 = "
                stosd
                mov     byte ptr [edi], 0       ; end with 0                             
                ;
                pop     edi
                ret
OutputABC EndP

; ----------------------------------------------------------------------------------------------
Main Proc
  Local WantContinue:DWord
  ; WantContinue is a sentinel value for while loop

    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)
       Invoke  InputABC, Addr NumberA, Addr _captionA, Addr _StringA
       Jc InputError ; jump on carry flag
       Invoke  InputABC, Addr NumberB, Addr _captionB, Addr _StringB
       Jc InputError ; jump on carry flag
       Invoke  InputABC, Addr NumberC, Addr _captionC, Addr _StringC
       Jc InputError ; jump on carry flag

       Invoke  FpuComp, Addr NumberA, Offset Number0, SRC1_REAL Or SRC2_REAL
       Or Eax, Eax   ; activate zero flag
       Jz ErrorInComp ;  jump equal to zero, if Eax = 0
       ; ------------------------------------
       ; If bit 0 of EAX=1 => NumberA=Number0
       ; ------------------------------------
       Shr Al, 1        ; mov bit 0 to Carry Flag
       Jc linear        ; jump on carry flag , NumberA = 0
       ;
       Call    calculateQuadraticRoots   ; no parameters its the same
                                         ; invoke calculateQuadraticRoots

       print   chr$(13, 10)
       Jmp     ToContinue
;.........................................
ErrorInComp:
        print   chr$(13, 10)
        print chr$(" Error comparing Number A against zero! ", 13, 10, 13, 10)
        jmp     ToContinue       
;..........................................
InputError:
            print   chr$(13, 10)
            print chr$(" Input Error ", 13, 10, 13, 10)
            jmp     ToContinue                     
;..........................................
linear:
       Invoke FpuComp, Addr NumberB, Offset Number0, SRC1_REAL Or SRC2_REAL
       Or Eax, Eax ; activate zero flag
       Jz ZeroErrors  ; jump equal to zero, if Eax = 0
       ; ------------------------------------
       ; If bit 0 of EAX=1 => NumberB=Number0
       ; ------------------------------------
       Shr Al, 1         ; mov bit 0 to Carry Flag
       Jc ZeroErrors     ; jump on carry flag ,  NumberB = 0
       
        Invoke   calculateLinearRoot, Addr NumberB, Addr NumberC
        Cmp Eax, 0  ; Compare Eax with 0
        Jne @F  ; jump not equal to 0
        ;
        print   chr$(13, 10)
        print   chr$(" Error calculating linear roots", 13, 10)
        jmp     ToContinue

       ;
@@:    print chr$(13, 10)
       print chr$("linear Equation : Bx + C ", 13, 10)
       print chr$(13, 10)
       print chr$(" Solution for linear equation : ", 13, 10)
       print chr$("-------------------------------", 13, 10)
       print chr$(" ")
       print real10$ (NumberB)

       Invoke FpuComp, Addr NumberC, Offset Number0, SRC1_REAL Or SRC2_REAL
       Shr Al, 1          ; mov bit 0 to Carry Flag
       Jc NumberCIs0      ; jump on carry flag  ,  NumberC = 0

       print chr$(" X + ")
       print ext$ (NumberC, 0, 5)
       Jmp Next

NumberCIs0:
   print chr$(" X ")
Next:
   print chr$(" = 0 ", 13, 10, 13, 10)
       print chr$(" X = ")
       print real10$ (_LinearRootX)
       print chr$(13, 10, 13, 10)
       print chr$(13, 10)
       Jmp ToContinue

ZeroErrors:
        print chr$(13, 10)
        print chr$(" Error, Numbers for A and B are zero! ", 13, 10, 13, 10)

ToContinue:
       Mov WantContinue, sval(input("Enter -1 to quit program : "))
       print chr$(13, 10)
       Invoke ClearScreen
    .EndW

  print chr$(13, 10)
  Ret
Main EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<   printQuadraticFormat will output the quadratic equation entered by  <<
;<<   user to the screen                                                  <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

printQuadraticFormat      proc
                    Call OutputABC
                    print chr$(" ")
                    print   offset _OutBuffer
                    print   chr$(13, 10)                                           
                    ret
printQuadraticFormat       endp
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  calculateLinearRoot procedure will calculate the root of the linear equation  <<
;<<  B x + C = 0  =>  x = - C / B
;<<  when NumberA is equal to 0 and NumberB is not equal to 0                      <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

calculateLinearRoot Proc  pNumB:DWord, pNumC:DWord
                    Local negativeNumC:Real10

     Lea Edx, negativeNumC ; Edx is the pointer address of negativeNumC
     Invoke FpuChs, pNumC, Edx, SRC1_REAL
     Cmp Eax, 0 ; compare Eax with 0 , activate the zero flag
     Je _rLinearRoot ; jump equal to 0
     ;
     Invoke FpuDiv, Edx, pNumB, Offset _LinearRootX, SRC1_REAL Or SRC2_REAL
                    ; EAX= 0 -> error
_rLinearRoot:
Ret
calculateLinearRoot EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<<  calculateXRoots procedure will calculate the two real roots in the quadratic   <<
;<<  formula                                                                        <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateXRoots Proc pNumA:DWord, pNumB:DWord, pNumC:DWord

                ; pNumA is a pointer to NumA
                ; pNumB is a pointer to NumB
                ; pNumC is a pointer to NumC

                Local NumB2:Real10
                Local Num4AC:Real10
                Local NumB2_4AC:Real10
                Local RootB2_4AC:Real10
                Local Num2A:Real10
                ; NumB2 = NumberB * NumberB
                ; Num4AC = 4 * NumberA * NumberC
                ; NumB2_4AC = (NumberB * NumberB) - (4 * NumberA * NumberC)
                ; RootB2_4AC = sqrt(NumB2_4AC)
                ; Num2A = 2 * NumberA = denominator

                Local SOLX0:Real10
                Local SOLX1:Real10
                ; SOLX0 = first solution to quadratic formula
                ; SOLX1 = second solution to quadratic formula

                Lea Ebx, NumB2 ; Ebx is the pointer address of NumB2
                invoke  FpuMul, pNumB, pNumB, ebx, SRC1_REAL or SRC2_REAL
                Or Eax, Eax ; activate zero flag
                Jz _rRealRoots    ; jump on zero,  Eax = 0   , error -> exit
               
                Lea Ecx, Num4AC ; Ecx is the pointer address of Num4AC
                invoke  FpuMul, pNumA, pNumC, ecx, SRC1_REAL or SRC2_REAL
                Or Eax, Eax ; activate zero flag
                Jz _rRealRoots   ; jump on zero,  Eax = 0   , error -> exit
                ;
                invoke  FpuMul, ecx, offset Number4, ecx, SRC1_REAL or SRC2_REAL
                Or Eax, Eax ; activate zero flag
                Jz _rRealRoots    ; jump on zero,  Eax = 0   , error -> exit

                Lea Edx, NumB2_4AC ; Edx is the pointer address of NumB2_4AC
                invoke  FpuSub, ebx, ecx, edx, SRC1_REAL or SRC2_REAL
                Or Eax, Eax ; activate zero flag
                Jz _rRealRoots  ; jump on zero,  Eax = 0   , error -> exit
                ;
                ; Test if NumB2_4AC >= 0
                ; ----------------------
                invoke  FpuComp, edx, offset Number0, SRC1_REAL or SRC2_REAL
                Or Eax, Eax ; activate zero flag
                Jz _rRealRoots  ; jump on zero,  Eax = 0   , error -> exit
                ;
                test    al, 00000100B
                jz      @F
                ;
                ; complex roots: NumB2_4AC < 0
                ; ----------------------------
                Mov Eax, 2 ; -> roots are complex
                Clc        ; -> carry flag is cleared
                ret
                ;
@@:             Lea Ebx, RootB2_4AC  ; Ebx is the pointer address of RootB2_4AC
                invoke  FpuSqrt, edx, ebx, SRC1_REAL
                Or Eax, Eax  ; activate zero flag
                Jz _rRealRoots   ; jump on zero,  Eax = 0   , error -> exit

                Lea Ecx, SOLX0  ; Ecx is the pointer address of SOLXO
                invoke  FpuSub, ebx, pNumB, ecx, SRC1_REAL or SRC2_REAL
                Or Eax, Eax  ; activate zero flag
                Jz _rRealRoots   ; jump on zero,  Eax = 0   , error -> exit

                Lea Edx, SOLX1 ; Edx is the pointer address of SOLX1
                invoke  FpuAdd, ebx, pNumB, edx, SRC1_REAL or SRC2_REAL
                Or Eax, Eax  ; activate zero flag
                Jz _rRealRoots  ; jump on zero,  Eax = 0   , error -> exit

                Lea Ebx, Num2A  ; Ebx is the pointer address of Num2A
                invoke  FpuMul, pNumA, offset Number2, ebx, SRC1_REAL or SRC2_REAL
                Or Eax, Eax  ; activate zero flag
                Jz _rRealRoots  ; jump on zero,  Eax = 0   , error -> exit
                               
                ; SOLX0
                invoke  FpuDiv, ecx, ebx, offset _RootX0, SRC1_REAL or SRC2_REAL
                Or Eax, Eax  ; activate zero flag
                Jz _rRealRoots  ; jump on zero,  Eax = 0   , error -> exit
               
                ; SOLX1
                invoke  FpuDiv, edx, ebx, edx, SRC1_REAL or SRC2_REAL
                Or Eax, Eax ; activate zero flag
                Jz _rRealRoots  ; jump on zero,  Eax = 0   , error -> exit

                invoke  FpuMul, edx, offset Minus1, offset _RootX1, SRC1_REAL or SRC2_REAL
                Or Eax, Eax ; activate zero flag
                Jz _rRealRoots  ; jump on zero,  Eax = 0   , error -> exit
                ;
                Mov Eax, 1  ; -> roots are real
                Clc         ; -> carry flag is cleared
                ret
                ;
                ; EAX = 0 => Error
                ;
_rRealRoots:   

                Stc ; -> set flag
                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

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

      Invoke calculateXRoots, Addr NumberA, Addr NumberB, Addr NumberC
      Jc _ExitProc  ; jump on carry flag

      Cmp Eax, 2  ;  Compare Eax with 2
      Je @F       ;  jump equal to 2

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

      Invoke printQuadraticFormat

      print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
                                 ; outputted to the screen
      print chr$(" X = ")
      print real10$ (_RootX0)   ; print the real number of one real root
                                ; in the quadratic formula
      print chr$(13, 10)
      print chr$("  1 ", 13, 10, 13, 10)
      print chr$(" X = ")
      print real10$ (_RootX1)   ; 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)

      Ret                       ; exit here

@@:
      print chr$(13, 10)
      print chr$(" There are no real solutions for the quadratic equation : ", 13, 10)
      print chr$("---------------------------------------------------------", 13, 10)

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

      Invoke printQuadraticFormat

      print chr$(13, 10, " This equation has complex roots! ")
      print chr$(13, 10, 13, 10) ; two carriage return line feeds to the screen
      Ret                        ; exit here
;......................................................
_ExitProc:
        print chr$(13, 10)
        print chr$(" An Error occured while calculating the roots", 13, 10)
    Ret
calculateQuadraticRoots EndP
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
End     start
; ##############################################################################################


etow

Hi

Here is the program in zip file for quadratic formula to solve quadratic equation for real solutions:

[attachment deleted by admin]