Hi I am having trouble with my code below:
--------------------------------------------------------------------------------------------------------------------------
.686 ; create 32 bit code
.Model flat, StdCall ;32 bit memory model
Option CaseMap :none ; case sensitive
Include \masm32\include\windows.inc
Include \masm32\macros\macros.asm ; MASM support macros
; -----------------------------------------------------------------
; include files that have MASM format prototypes for function calls
; -----------------------------------------------------------------
Include \masm32\include\masm32rt.inc
; ------------------------------------------------
; Library files that have definitions for function
; exports and tested reliable prebuilt code.
; ------------------------------------------------
IncludeLib \masm32\lib\msvcrt.lib
.Code
start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Call Main
inkey ; pause the screen while waiting for user to press any key
; to continue
exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Main Proc
Local WantContinue:DWord
Local NumberA:DWord
Local NumberB:DWord
Local NumberC:DWord
Mov WantContinue, 0
.While ((WantContinue >= 0) && (WantContinue < -1))
print chr$(13, 10)
Mov NumberA, sval(input("Enter an integer value for Number A : "))
Mov NumberB, sval(input("Enter an integer value for Number B : "))
Mov NumberC, sval(input("Enter an integer value for Number C : "))
print chr$(13, 10)
Call calculateQuadraticRoots NumberA, NumberB, NumberC
print chr$(13, 10)
Mov WantContinue, sval(input("Enter -1 to quit program : "))
print chr$(13, 10)
.EndW
Ret
Main EndP
calculateQuadraticRoots Proc A_Number:DWord, B_Number:DWord, C_Number:DWord
Local squareRootNumber:DWord
Local partSquareRootNumber:DWord
Local BSquared:DWord
Local NegB:DWord
Local resultOfSquareRoot:DWord
Neg B_Number
Mov Eax, B_Number
Add Eax, Eax
Mov BSquared, Eax ; b^2
Mov Eax, A_Number
IMul C_Number
Mov Ebx, Eax
Mov Eax, -4 ; -4 * a * c
Mov Eax, partSquareRootNumber
Mov Ebx, squareRootNumber
Add Ebx, Eax
Mov squareRootNumber, Ebx
Call Intsqrt squareRootNumber
Mov resultOfSquareRoot, Eax
Ret
calculateQuadraticRoots EndP
End start
----------------------------------------------------------------------------------------------
I am receiving the following error messages:
============== proj4 - Debug ==============
Assembling: Module1
Module1.asm(3) : warning A4011: multiple .MODEL directives found : .MODEL ignored
------------------------------------------
WARNING Duplicate include file windows.inc
------------------------------------------
\masm32\include\masm32rt.inc(33) : warning A4011: multiple .MODEL directives found : .MODEL ignored
------------------------------------------
WARNING Duplicate include file windows.inc
------------------------------------------
-----------------------------------------
WARNING Duplicate include file user32.inc
-----------------------------------------
-----------------------------------------
WARNING Duplicate include file kernel32.inc
-----------------------------------------
Module1.asm(44) : error A2008: syntax error : ,
Module1.asm(77) : error A2206: missing operator in expression
Errors ocurred.
etow,
You have a strange way to learn. Looks like try, try, try until it work, instead of learning how to do.
You already got your answer for duplicates and .MODEL
http://www.masm32.com/board/index.php?topic=8576.msg62394#msg62394
http://www.masm32.com/board/index.php?topic=8576.msg62395#msg62395
When you see "Module1.asm(44) : error A2008: syntax error : ," the "Module1.asm(44)" means that the error is at line 44
Look for "Using invoke" in the help file "masm32" in the help folder of MASM32 Project
etow,
Here is your source with the minimal corrections necessary to make it assemble and link without error.
;;INCLUDED IN masm32rt.inc: .686 ;create 32 bit code
;;INCLUDED IN masm32rt.inc: .Model flat, StdCall ;32 bit memory model
;;INCLUDED IN masm32rt.inc: Option CaseMap :none ;case sensitive
;;INCLUDED IN masm32rt.inc: Include \masm32\include\windows.inc
;;INCLUDED IN masm32rt.inc: Include \masm32\macros\macros.asm
Include \masm32\include\masm32rt.inc
;;INCLUDED IN masm32rt.inc: IncludeLib \masm32\lib\msvcrt.lib
.Code
start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Call Main
inkey ; pause the screen while waiting for user to press any key
; to continue
exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; ----------------------------------------------------------------
; This is the prototype for the calculateQuadraticRoots procedure:
; ----------------------------------------------------------------
calculateQuadraticRoots PROTO :DWord,:DWord,:DWord
Main Proc
Local WantContinue:DWord
Local NumberA:DWord
Local NumberB:DWord
Local NumberC:DWord
Mov WantContinue, 0
.While ((WantContinue >= 0) && (WantContinue < -1))
print chr$(13, 10)
Mov NumberA, sval(input("Enter an integer value for Number A : "))
Mov NumberB, sval(input("Enter an integer value for Number B : "))
Mov NumberC, sval(input("Enter an integer value for Number C : "))
print chr$(13, 10)
; --------------------------------------------------
; To pass arguments in this way you must use invoke.
; And to use invoke for a procedure that is defined
; after it is invoked, you must provide a prototype
; so MASM will know how to call it.
; --------------------------------------------------
;Call calculateQuadraticRoots NumberA, NumberB, NumberC
invoke calculateQuadraticRoots, NumberA, NumberB, NumberC
print chr$(13, 10)
Mov WantContinue, sval(input("Enter -1 to quit program : "))
print chr$(13, 10)
.EndW
Ret
Main EndP
; -----------------------------------------------------------------
; This is the definition for the calculateQuadraticRoots procedure:
; -----------------------------------------------------------------
calculateQuadraticRoots Proc A_Number:DWord, B_Number:DWord, C_Number:DWord
Local squareRootNumber:DWord
Local partSquareRootNumber:DWord
Local BSquared:DWord
Local NegB:DWord
Local resultOfSquareRoot:DWord
Neg B_Number
Mov Eax, B_Number
Add Eax, Eax
Mov BSquared, Eax ; b^2
Mov Eax, A_Number
IMul C_Number
Mov Ebx, Eax
Mov Eax, -4 ; -4 * a * c
Mov Eax, partSquareRootNumber
Mov Ebx, squareRootNumber
Add Ebx, Eax
Mov squareRootNumber, Ebx
; ---------------------------------------------------
; To pass arguments in this way you must use invoke.
; IntSqrt is part of the MASM32 library, so the
; prototype is taken care of, but you must use the
; correct case for all procedure names, as well as
; all of your label and variable names.
; ---------------------------------------------------
;Call Intsqrt squareRootNumber
invoke IntSqrt, squareRootNumber
Mov resultOfSquareRoot, Eax
Ret
calculateQuadraticRoots EndP
End start
Quote from: etow on January 30, 2008, 03:13:23 PM
Mov Eax, B_Number
Add Eax, Eax
Mov BSquared, Eax ; b^2
etow,
i think you have an error here:
;
b^2 <= This is «b + b» or «b * b» ?????????????
Add Eax, Eax <= This is eax PLUS eax NOT eax * eax as you want
;................................................
You want something like this:
Mov Eax, B_Number
mov edx, eax
mul edx
Mov BSquared, Eax ; BSquared = EAX * EAX
RuiLoureiro
Here is my updated code below:
-------------------------------------------------------------------------------------
.686 ; create 32 bit code
.Model flat, StdCall ;32 bit memory model
Option CaseMap :none ; case sensitive
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\windows.inc
Include \masm32\macros\macros.asm ; MASM support macros
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; -----------------------------------------------------------------
; include files that have MASM format prototypes for function calls
; -----------------------------------------------------------------
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; ------------------------------------------------
; Library files that have definitions for function
; exports and tested reliable prebuilt code.
; ------------------------------------------------
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
IncludeLib \masm32\lib\msvcrt.lib
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
.Code
start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Call Main
inkey ; pause the screen while waiting for user to press any key
; to continue
exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Main Proc
Local WantContinue:DWord
Local NumberA:DWord
Local NumberB:DWord
Local NumberC:DWord
Mov WantContinue, 0
.While ((WantContinue >= 0) && (WantContinue < -1))
print chr$(13, 10)
print chr$("Quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
Mov NumberA, sval(input("Enter an integer value for Number A : "))
Mov NumberB, sval(input("Enter an integer value for Number B : "))
Mov NumberC, sval(input("Enter an integer value for Number C : "))
Invoke calculateQuadraticRoots, NumberA, NumberB, NumberC
print chr$(13, 10)
Mov WantContinue, sval(input("Enter -1 to quit program : "))
print chr$(13, 10)
.EndW
Ret
Main EndP
calculateQuadraticRoots Proc A_Number:DWord, B_Number:DWord, C_Number:DWord
Local squareRootNumber:DWord
Local partSquareRootNumber:DWord
Local BSquared:DWord
Local originalB_Number:DWord
Local negativeB:DWord
Local resultOfSquareRoot:DWord
Local numerator1:DWord
Local numerator2:DWord
Local denominator:DWord
Local realRoot1:FLOAT
Local realRoot2:FLOAT
; Quadratic Equation: (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)
Mov Ebx, B_Number
Mov originalB_Number, Ebx
Mov Eax, B_Number
Mov Edx, Eax
Mul Edx
Mov BSquared, Eax ; b^2
Mov Eax, A_Number
IMul C_Number
Mov Ebx, Eax
Mov Eax, -4
IMul Ebx ; -4 * a * c
Mov partSquareRootNumber, Eax
Mov Eax, BSquared
Mov Ebx, partSquareRootNumber
Add Eax, Ebx
Mov squareRootNumber, Eax ; b^2 - 4 * a * c
.If (squareRootNumber >= 0)
Invoke IntSqrt, squareRootNumber
Mov resultOfSquareRoot, Eax
Neg B_Number
Mov Eax, B_Number
Mov negativeB, Eax ; -b
Mov Eax, 2
IMul A_Number
Mov denominator, Eax ; 2 * a
Mov Eax, negativeB
Mov Ebx, resultOfSquareRoot
Add Eax, Ebx
Mov numerator1, Eax ; (- b + sqrt(b^2 - 4 * a * c))
Neg resultOfSquareRoot
Mov Eax, resultOfSquareRoot
Mov Ebx, negativeB
Add Eax, Ebx
Mov numerator2, Eax ; (- b - sqrt(b^2 - 4 * a * c))
Mov Eax, numerator1
Div denominator
Mov realRoot1, Eax ; (-b + sqrt(b^2 - 4 * a * c)) / (2 * a)
Mov Eax, numerator2
Div denominator
Mov realRoot2, Eax ; (-b - sqrt(b^2 - 4 * a * c)) / (2 * a)
print chr$(13, 10)
print chr$(" Solutions for quadratic equation : ")
.If (A_Number == 1)
print chr$("X^2 ")
.ElseIf
print str$(A_Number)
print chr$("X^2 ")
.EndIf
.If (originalB_Number == 1)
print chr$("+ X ")
.ElseIf (originalB_Number < SDWord Ptr - 1)
print str$(originalB_Number)
print chr$("X ")
.ElseIf (originalB_Number == -1)
print chr$("- X ")
.ElseIf (originalB_Number > 1)
print chr$("+ ")
print str$(originalB_Number)
print chr$("X ")
.EndIf
.If (C_Number < SDWord Ptr - 1)
print str$(C_Number)
.ElseIf (C_Number == -1)
print chr$("- ")
print chr$("1")
.ElseIf (C_Number > 0)
print chr$("+ ")
print str$(C_Number)
.EndIf
print chr$(13, 10)
print chr$(" X1 = ")
print str$(realRoot1)
print chr$(13, 10)
print chr$(" X2 = ")
print str$(realRoot2)
print chr$(13, 10)
.ElseIf (squareRootNumber < SDWord Ptr 0)
print chr$(13, 10)
print chr$("There are no real solutions to this quadratic equation!")
print chr$(13, 10)
.EndIf
Ret
calculateQuadraticRoots EndP
End start
------------------------------------------------------------------------------------------
I can not get the second X solution to the quadratic equation to calculate correctly
If I enter 1 for Number A, enter 0 for Number B, and enter -4 for Number C,
X1 = 2
X2 = 2147483646
Why is X2 this number above instead of -2?
Please help me.
Thanks
etow,
1. try to simplify. Dont use a lot of variables that you dont need.
You can use registers to save some intermediate results (ex: ebx, esi, edi )
Dont modify the input values like *** Neg B_Number ***. Use
*** negativeB variable *** if you want .
2. I dont know where is the error, your code is not easy to follow. Here my help
; Quadratic Equation: (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)
;Mov Ebx, B_Number ; dont need
;Mov originalB_Number, Ebx ; dont need
;
; b ^ 2
; -----
Mov eax, B_Number
Mov edx, eax
IMul edx
;Mov BSquared, eax ; dont need
mov ebx, eax ; EBX = b ^ 2
;
; 4 * a * c
; ---------
mov ecx, 4
Mov eax, A_Number
IMul C_Number
IMul ecx ; EAX = 4 * a * c
;
; b ^ 2 - 4 * a * c
; -----------------
sub ebx, eax ; EBX = b ^ 2 - 4 * a * c
Mov squareRootNumber, ebx
;
; Test
;
.If (squareRootNumber >= 0)
Invoke IntSqrt, squareRootNumber
Mov resultOfSquareRoot, Eax
.............
RuiLoureiro
Hi
My updated code below:
-------------------------------------------------------------------------
.686 ; create 32 bit code
.Model flat, StdCall ;32 bit memory model
Option CaseMap :none ; case sensitive
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\windows.inc
Include \masm32\macros\macros.asm ; MASM support macros
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; -----------------------------------------------------------------
; include files that have MASM format prototypes for function calls
; -----------------------------------------------------------------
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; ------------------------------------------------
; Library files that have definitions for function
; exports and tested reliable prebuilt code.
; ------------------------------------------------
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
IncludeLib \masm32\lib\msvcrt.lib
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
.Code
start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Call Main
inkey ; pause the screen while waiting for user to press any key
; to continue
exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateQuadraticRoots Proto:DWord, :DWord, :DWord
Main Proc
Local WantContinue:DWord
Local NumberA:DWord
Local NumberB:DWord
Local NumberC:DWord
Mov WantContinue, 0
.While ((WantContinue >= 0) && (WantContinue < -1))
print chr$(13, 10)
print chr$("Quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
Mov NumberA, sval(input("Enter an integer value for Number A : "))
Mov NumberB, sval(input("Enter an integer value for Number B : "))
Mov NumberC, sval(input("Enter an integer value for Number C : "))
Invoke calculateQuadraticRoots, NumberA, NumberB, NumberC
print chr$(13, 10)
Mov WantContinue, sval(input("Enter -1 to quit program : "))
print chr$(13, 10)
.EndW
Ret
Main EndP
calculateQuadraticRoots Proc A_Number:DWord, B_Number:DWord, C_Number:DWord
Local squareRootNumber:DWord
Local negativeB:DWord
Local resultOfSquareRoot:DWord
Local numerator1:DWord
Local numerator2:DWord
Local denominator:DWord
Local realRoot1:Real4
Local realRoot2:Real4
; Quadratic Equation: (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)
.If (A_Number != 0)
Mov Eax, B_Number
Mov Edx, Eax
Mul Edx
Mov Ebx, Eax ; Ebx = b^2
Mov Ecx, -4
Mov Eax, A_Number
Mul C_Number
Mul Ecx ; Eax = -4 * a * c
Add Ebx, Eax
Mov squareRootNumber, Ebx ; ebx = b^2 - 4 * a * c
.If (squareRootNumber > SDWord Ptr - 1)
Invoke IntSqrt, squareRootNumber
Mov resultOfSquareRoot, Eax
Mov Eax, B_Number
Neg Eax
Mov negativeB, Eax ; -b
Mov Eax, 2
Mul A_Number
Mov denominator, Eax ; eax = 2 * a
Mov Eax, negativeB
Mov Ebx, resultOfSquareRoot
Add Eax, Ebx
Mov numerator1, Eax ; eax = (- b + sqrt(b^2 - 4 * a * c))
Mov Ebx, resultOfSquareRoot
Neg Ebx
Mov Eax, negativeB
Add Eax, Ebx
Mov numerator2, Eax ; eax = (- b - sqrt(b^2 - 4 * a * c))
Mov Eax, numerator1
Div denominator
Mov realRoot1, Eax ; eax = (-b + sqrt(b^2 - 4 * a * c)) / (2 * a)
Mov Eax, numerator2
Div denominator
Mov realRoot2, Eax ; eax = (-b - sqrt(b^2 - 4 * a * c)) / (2 * a)
print chr$(13, 10)
print chr$(" Solutions for quadratic equation : ")
.If (A_Number == -1)
print chr$("-X^2 ")
.ElseIf (A_Number == 1)
print chr$("X^2 ")
.ElseIf ((A_Number > 1) || (A_Number < SDWord Ptr - 1))
print str$(A_Number)
print chr$("X^2 ")
.EndIf
.If (B_Number < SDWord Ptr - 1)
print str$(B_Number)
print chr$("X ")
.ElseIf (B_Number == -1)
print chr$("- X ")
.ElseIf (B_Number == 1)
print chr$("+ X ")
.ElseIf (B_Number > 1)
print chr$("+ ")
print str$(B_Number)
print chr$("X ")
.EndIf
.If (C_Number < SDWord Ptr - 1)
print str$(C_Number)
.ElseIf (C_Number == -1)
print chr$("- ")
print chr$("1")
.ElseIf (C_Number > 0)
print chr$("+ ")
print str$(C_Number)
.EndIf
print chr$(13, 10)
print chr$(" X1 = ")
print str$(realRoot1)
print chr$(13, 10)
print chr$(" X2 = ")
print str$(realRoot2)
print chr$(13, 10)
.ElseIf (squareRootNumber <= SDWord Ptr - 1)
print chr$(13, 10)
print chr$("There are no real solutions for the quadratic equation : ")
.If (A_Number == -1)
print chr$("-X^2 ")
.ElseIf (A_Number == 1)
print chr$("X^2 ")
.ElseIf ((A_Number > 1) || (A_Number < SDWord Ptr - 1))
print str$(A_Number)
print chr$("X^2 ")
.EndIf
.If (B_Number < SDWord Ptr - 1)
print str$(B_Number)
print chr$("X ")
.ElseIf (B_Number == -1)
print chr$("- X ")
.ElseIf (B_Number == 1)
print chr$("+ X ")
.ElseIf (B_Number > 1)
print chr$("+ ")
print str$(B_Number)
print chr$("X ")
.EndIf
.If (C_Number < SDWord Ptr - 1)
print str$(C_Number)
.ElseIf (C_Number == -1)
print chr$("- ")
print chr$("1")
.ElseIf (C_Number > 0)
print chr$("+ ")
print str$(C_Number)
.EndIf
print chr$(" !", 13, 10)
.EndIf
.ElseIf
print chr$(13, 10)
print chr$("Error, Division by zero!", 13, 10)
.EndIf
Ret
calculateQuadraticRoots EndP
End start
---------------------------------------------------------------------------------------------
I am not sure if realRoot1 and realRoot2 are correct in calculation.
Quote from: etow on January 30, 2008, 11:59:26 PM
Mov Eax, numerator1
Div denominator
Mov realRoot1, Eax ; eax = (-b + sqrt(b^2 - 4 * a * c)) / (2 * a)
Mov Eax, numerator2
Div denominator
Mov realRoot2, Eax ; eax = (-b - sqrt(b^2 - 4 * a * c)) / (2 * a)
I am not sure if realRoot1 and realRoot2 are correct in calculation.
etow,
*** Div denominator *** divides
EDX:EAX by
denominator. Whats the value
of EDX ?
Put xor edx, edx or mov edx, 0 before div.
After *** Mov numerator1, Eax *** ; eax = (- b + sqrt(b^2 - 4 * a * c))
you dont need to repeat *** Mov Ebx, resultOfSquareRoot ***
because ebx =resultOfSquareRoot.
RuiLoureiro
hi
how do you do real or floating point division instead of integer division?
Thanks
Quote from: etow on January 31, 2008, 02:29:50 PM
hi
how do you do real or floating point division instead of integer division?
Thanks
As far as i know, using FPU.
RuiLoureiro
Hi RuiLoureiro,
Can you give me an example how to use FPU?
Thanks
I found out the problem.
the code below:
Mov Eax, numerator1
IDiv denominator
Mov realRoot1, Eax ; eax = (-b + sqrt(b^2 - 4 * a * c)) / (2 * a)
Mov Eax, numerator2
IDiv denominator
Mov realRoot2, Eax ; eax = (-b - sqrt(b^2 - 4 * a * c)) / (2 * a)
-------------------------------------------------------------------------------------------------------
if the result in Eax is positive then the result is okay
but if the result in Eax is negative then the result is not good or bad result.
How do I fix this?
Please help
Thanks
Quote from: etow on January 31, 2008, 04:46:26 PM
I found out the problem.
-------------------------------------------------------------------------------------------------------
if the result in Eax is positive then the result is okay
but if the result in Eax is negative then the result is not good or bad result.
Hi etow,
1. Its not correct. When we want to divide a dword value like numerator1 by a dword value like
denominator we need to put edx to 0 or the signal of EAX into EDX.
IDiv denominator divide EDX:EAX (64 bits) by denominator. Its clear.
2. About FPU, see fpulib in MASM32 and tuturial\fputute written by Raymond Filiatreault.
He should have many examples to help you. The work i am doing now doesnt use FPU, so i
have not an example to give you. I used it some years ago i dont know where are my routines.
Sorry.
RuiLoureiro
hi
*** Div denominator *** divides EDX:EAX by denominator. Whats the value
of EDX ?
Put xor edx, edx or mov edx, 0 before div.
After *** Mov numerator1, Eax *** ; eax = (- b + sqrt(b^2 - 4 * a * c))
Edx register is 0 after putting mov edx, 0 before div. I tried the above but it does not work.
If the eax is negative for both realRoot1 and realRoot2 values, then answers are 2147483647.
If the eax is negative for either realRoot1 or realRoot2 values then the answer is 2147483647.
Here is my updated code below:
.686 ; create 32 bit code
.Model flat, StdCall ;32 bit memory model
Option CaseMap :none ; case sensitive
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\windows.inc
Include \masm32\macros\macros.asm ; MASM support macros
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; -----------------------------------------------------------------
; include files that have MASM format prototypes for function calls
; -----------------------------------------------------------------
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; ------------------------------------------------
; Library files that have definitions for function
; exports and tested reliable prebuilt code.
; ------------------------------------------------
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
IncludeLib \masm32\lib\msvcrt.lib
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
.Code
start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Call Main
inkey ; pause the screen while waiting for user to press any key
; to continue
exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateQuadraticRoots Proto:DWord, :DWord, :DWord
Main Proc
Local WantContinue:DWord
Local NumberA:DWord
Local NumberB:DWord
Local NumberC:DWord
Mov WantContinue, 0
.While ((WantContinue >= 0) && (WantContinue < -1))
print chr$(13, 10)
print chr$("Quadratic Equation : Ax^2 + Bx + C ", 13, 10, 13, 10)
Mov NumberA, sval(input("Enter an integer value for Number A : "))
Mov NumberB, sval(input("Enter an integer value for Number B : "))
Mov NumberC, sval(input("Enter an integer value for Number C : "))
Invoke calculateQuadraticRoots, NumberA, NumberB, NumberC
print chr$(13, 10)
Mov WantContinue, sval(input("Enter -1 to quit program : "))
print chr$(13, 10)
.EndW
Ret
Main EndP
calculateQuadraticRoots Proc A_Number:DWord, B_Number:DWord, C_Number:DWord
Local squareRootNumber:DWord
Local negativeB:DWord
Local resultOfSquareRoot:DWord
Local numerator1:DWord
Local numerator2:DWord
Local denominator:DWord
Local realRoot1:DWord
Local realRoot2:DWord
; Quadratic Equation: (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)
.If (A_Number != 0)
Mov Eax, B_Number
Mov Edx, Eax
IMul Edx
Mov Ebx, Eax ; Ebx = b^2
Mov Ecx, -4
Mov Eax, A_Number
IMul C_Number
IMul Ecx ; Eax = -4 * a * c
Add Ebx, Eax
Mov squareRootNumber, Ebx ; Ebx = b^2 - 4 * a * c
.If (squareRootNumber > SDWord Ptr - 1)
Invoke IntSqrt, squareRootNumber
Mov resultOfSquareRoot, Eax
Mov Eax, B_Number
Neg Eax
Mov negativeB, Eax ; Eax = -b
Mov Eax, 2
IMul A_Number
Mov denominator, Eax ; Eax = 2 * a
Mov Eax, negativeB
Mov Ebx, resultOfSquareRoot
Add Eax, Ebx
Mov numerator1, Eax ; Eax = (- b + sqrt(b^2 - 4 * a * c))
Neg Ebx
Mov Eax, negativeB
Add Eax, Ebx
Mov numerator2, Eax ; Eax = (- b - sqrt(b^2 - 4 * a * c))
Mov Eax, numerator1
IDiv denominator
Mov realRoot1, Eax ; Eax = (-b + sqrt(b^2 - 4 * a * c)) / (2 * a)
Mov Eax, numerator2
IDiv denominator
Mov realRoot2, Eax ; Eax = (-b - sqrt(b^2 - 4 * a * c)) / (2 * a)
print chr$(13, 10)
print chr$(" Solutions for quadratic equation : ")
.If (A_Number == -1)
print chr$("-X^2 ")
.ElseIf (A_Number == 1)
print chr$("X^2 ")
.ElseIf ((A_Number > 1) || (A_Number < SDWord Ptr - 1))
print str$(A_Number)
print chr$("X^2 ")
.EndIf
.If (B_Number < SDWord Ptr - 1)
print str$(B_Number)
print chr$("X ")
.ElseIf (B_Number == -1)
print chr$("- X ")
.ElseIf (B_Number == 1)
print chr$("+ X ")
.ElseIf (B_Number > 1)
print chr$("+ ")
print str$(B_Number)
print chr$("X ")
.EndIf
.If (C_Number < SDWord Ptr - 1)
print str$(C_Number)
.ElseIf (C_Number == -1)
print chr$("- ")
print chr$("1")
.ElseIf (C_Number > 0)
print chr$("+ ")
print str$(C_Number)
.EndIf
print chr$(13, 10, 13, 10)
print chr$(" X1 = ")
print str$(realRoot1)
print chr$(13, 10)
print chr$(" X2 = ")
print str$(realRoot2)
print chr$(13, 10)
.ElseIf (squareRootNumber <= SDWord Ptr - 1)
print chr$(13, 10)
print chr$("There are no real solutions for the quadratic equation : ")
.If (A_Number == -1)
print chr$("-X^2 ")
.ElseIf (A_Number == 1)
print chr$("X^2 ")
.ElseIf ((A_Number > 1) || (A_Number < SDWord Ptr - 1))
print str$(A_Number)
print chr$("X^2 ")
.EndIf
.If (B_Number < SDWord Ptr - 1)
print str$(B_Number)
print chr$("X ")
.ElseIf (B_Number == -1)
print chr$("- X ")
.ElseIf (B_Number == 1)
print chr$("+ X ")
.ElseIf (B_Number > 1)
print chr$("+ ")
print str$(B_Number)
print chr$("X ")
.EndIf
.If (C_Number < SDWord Ptr - 1)
print str$(C_Number)
.ElseIf (C_Number == -1)
print chr$("- ")
print chr$("1")
.ElseIf (C_Number > 0)
print chr$("+ ")
print str$(C_Number)
.EndIf
print chr$(" !", 13, 10)
.EndIf
.ElseIf
print chr$(13, 10)
print chr$("Error, Division by zero!", 13, 10)
.EndIf
Ret
calculateQuadraticRoots EndP
End start
----------------------------------------------------------------------------------
I am not sure why Eax register outputs 2147483647 for realRoot1 or realRoot2 or for both?
Can anyone help me?
Thanks
hint: 2147483647 decimal = 7FFFFFFF hex = -1 with the topmost bit removed.
for the quadratic equation x^2 + 7x + 12
X = -3
1
X = -4
2
How can I get these answers for negative numbers above since the highest is 2147483647 positive decimal number?
How can I convert these long integer values into negative numbers?
Please help
Thanks
You have not worked
with this in a
higher level language ?
well I did not have to worry about this in high level language.
I did not have to display anything negative before
Ok, sorry I wasn't more explicit. If you look at your code:
Mov eax, numerator2
IDiv denominator
Mov realRoot2, eax ; Eax = (-b - sqrt(b^2 - 4 * a * c)) / (2 * a)
You are doing a double word divide. Look at the description for idiv. It says:
Divides (signed) the value in the AL, AX, or EAX register by the source
operand and stores the result in the AX, DX:AX, or EDX:EAX registers.
The source operand can be a general-purpose register or a memory location.
Notice the notation EDX:EAX
You need to convert the dword in eax to a qword in EDX:EAX before the division.
Mov eax, numerator2
cdq
IDiv denominator
Mov realRoot2, eax ; Eax = (-b - sqrt(b^2 - 4 * a * c)) / (2 * a)
You have to be real careful about this stuff.
Also, in you last posting of your program, it starts:
.686 ; create 32 bit code
.Model flat, StdCall ;32 bit memory model
Option CaseMap :none ; case sensitive
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\windows.inc
Include \masm32\include\macros.asm ; MASM support macros
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; -----------------------------------------------------------------
; include files that have MASM format prototypes for function calls
; -----------------------------------------------------------------
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; ------------------------------------------------
; Library files that have definitions for function
; exports and tested reliable prebuilt code.
; ------------------------------------------------
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
IncludeLib \masm32\lib\msvcrt.lib
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
if you look at \masm32\include\masm32rt.inc
you will see it contains all the rest of the startup code, so delete everything else, or delete masm32rt.inc and add in what's missing.
Quote from: etow on February 01, 2008, 01:11:29 AM
How can I convert these long integer values into negative numbers?
Thanks
Hi etow,
1. I dont know what is your doubt. I didnt understand. In any way
2. In the Register of Flags there is a flag SIGN (SF). If you have a number in EAX,
or eax, eax activate the sign flag.
3. To get the digits of EAX, divide it successively by 10 and take the remainders in reverse
order. If the number is negative, put the sign - before.
mov ebx, 0 ; means the number is positive -> put sign + or not
or eax, eax
jns convert ; jump if not sign
;
mov ebx, 1 ; means the number is negative -> put sign -
neg eax ; eax is positive
;
; convert positive EAX
;
convert:
This help you ? Sorry if not
RuiLoureiro
Hi RuiLoureiro,
Thanks for your help
I got it to work.
Hi
Does anyone know if there is a square root function for real or floating point numbers
that I could use to get real or floating point number results?
Also how do I display these results to a certain decimal point?
Here is my updated code below:
-----------------------------------------------------------------------------------------------
.686 ; create 32 bit code
.Model flat, StdCall ;32 bit memory model
Option CaseMap :none ; case sensitive
;The MASM32 Runtime Library include file.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
.Code
start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Call Main
inkey ; pause the screen while waiting for user to press any key
; to continue
exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateQuadraticRoots Proto:DWord, :DWord, :DWord
Main Proc
Local WantContinue:DWord
Local NumberA:DWord
Local NumberB:DWord
Local NumberC: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 to 0 to start while loop
.While ((WantContinue >= 0) && (WantContinue < -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)
Mov NumberA, sval(input("Enter an integer value for Number A : "))
Mov NumberB, sval(input("Enter an integer value for Number B : "))
Mov NumberC, sval(input("Enter an integer value for Number C : "))
Invoke calculateQuadraticRoots, NumberA, NumberB, NumberC
print chr$(13, 10)
Mov WantContinue, sval(input("Enter -1 to quit program : "))
print chr$(13, 10)
.EndW
Ret
Main EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<< calculateQuadraticRoots procedure will calculate two real roots <<
;<< of a quadratic equation by receiving three coefficients from <<
;<< user as input <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateQuadraticRoots Proc A_Number:DWord, B_Number:DWord, C_Number:DWord
Local squareRootNumber:DWord
Local negativeB:DWord
Local resultOfSquareRoot:DWord
Local numerator1:DWord
Local numerator2:DWord
Local denominator:DWord
Local signedRoot1[1024]:Byte
Local signedRoot2[1024]:Byte
; squareRootNumber is the square root part of the quadratic formula
; negativeB is the negation of b of the quadratic formula
; resultOfSquareRoot is the result after getting square root of number
; of the quadratic formula
; signedRoot1 and signedRoot2 are the string arrays which are the two X solutions
; to the quadratic formula
; numerator1 and numerator2 are the numerator part of the quadratic formula
; that has two solutions
; denominator is the denominator of the quadratic formula
; Eax, Ebx, Ecx, Edx, Esi, Edi are registers
; Quadratic Formula: x = (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)
.If (A_Number != 0) ; if A_Number is not equal to zero
Mov Eax, B_Number ; set Eax = B_Number
Mov Edx, Eax ; set Edx = Eax
IMul Edx ; Eax = Eax * Edx
Mov Ebx, Eax ; set Ebx = Eax
; Ebx = b^2
Mov Ecx, -4 ; set Ecx = -4
Mov Eax, A_Number ; set Eax = A_Number
IMul C_Number ; Eax = Eax * C_NUmber
IMul Ecx ; Eax = Eax * Ecx
; Eax = -4 * a * c
Add Ebx, Eax ; Ebx = Ebx + Eax
Mov squareRootNumber, Ebx ; set squareRootNumber = Ebx
; Ebx = b^2 - 4 * a * c
.If (squareRootNumber > SDWord Ptr - 1)
Mov signedRoot1, 0 ; set signedRoot1 string array to empty
Mov signedRoot2, 0 ; set signedRoot2 string array to empty
Invoke IntSqrt, squareRootNumber ; call square root function
Mov resultOfSquareRoot, Eax ; set resultOfSquareRoot = Eax
Mov Eax, B_Number ; set Eax = B_Number
Neg Eax ; Eax = Eax * -1
Mov negativeB, Eax ; set negativeB = Eax
; Eax = -b
Mov Eax, 2 ; set Eax = 2
IMul A_Number ; Eax = Eax * A_Number
Mov denominator, Eax ; set denominator = Eax
; Eax = 2 * a
Mov Eax, negativeB ; set Eax = negativeB
Mov Ebx, resultOfSquareRoot ; set Ebx = resultOfSquareRoot
Add Eax, Ebx ; Eax = Eax + Ebx
Mov numerator1, Eax ; set numerator1 = Eax
; Eax = (- b + sqrt(b^2 - 4 * a * c))
Neg Ebx ; Ebx = Ebx * -1
; - resultOfSquareRoot
Mov Eax, negativeB ; set Eax = negativeB
Add Eax, Ebx ; Eax = Eax + Ebx
Mov numerator2, Eax ; set numerator2 = Eax
; Eax = (- b - sqrt(b^2 - 4 * a * c))
Mov Eax, numerator1 ; set Eax = numerator1
Cdq ; convert to double quad word or 64-bit long word
IDiv denominator ; Eax = Eax / denominator
; Eax = (-b + sqrt(b^2 - 4 * a * c)) / (2 * a)
Mov Ebx, 0 ; number is positive
Or Eax, Eax ; activate sign flag
Jns positive1 ; jump to positive1 label if positive number
Mov Ebx, 1 ; number is negative
Neg Eax ; Eax = Eax * -1
Mov Esi, cat$(Addr signedRoot1, "-", str$(Eax)) ; concatenate negative sign
; along with positive number
; in Eax into signedRoot1
; string array
Jmp nextRoot ; jump to nextRoot label
positive1:
Mov Esi, cat$(Addr signedRoot1, str$(Eax)) ; concatenate positive number in
; in Eax into signedRoot1 string
; array
nextRoot:
Mov Eax, numerator2 ; set Eax = numerator2
Cdq ; convert to double quad word or 64-bit long word
IDiv denominator ; Eax = Eax / denominator
; Eax = (-b - sqrt(b^2 - 4 * a * c)) / (2 * a)
Mov Ebx, 0 ; number is positive
Or Eax, Eax ; activate sign flag
Jns positive2 ; jump to positive2 label if positive number
Mov Ebx, 1 ; number is negative
Neg Eax ; Eax = Eax * -1
Mov Edi, cat$(Addr signedRoot2, "-", str$(Eax)) ; concatenate negative sign
; along with a positive number
; in Eax into signedRoot2
; string array
Jmp output ; jump to output label
positive2:
Mov Edi, cat$(Addr signedRoot2, str$(Eax)) ; concatenate positive number in
; in Eax into signedRoot2 string
; array
output:
print chr$(13, 10) ; a carriage return line feed will be outputted to the
; screen
print chr$(" Solutions for quadratic equation : ")
; The following if else statements output the format of the quadratic
; equation
.If (A_Number == -1) ; if A_Number equals to -1
print chr$("-X^2 ")
.ElseIf (A_Number == 1) ; if A_Number equals to 1
print chr$("X^2 ")
.ElseIf ((A_Number > 1) || (A_Number < SDWord Ptr - 1)) ; if A_Number greater
; than 1 OR A_Number less than -1
print str$(A_Number)
print chr$("X^2 ")
.EndIf
.If (B_Number < SDWord Ptr - 1) ; if B_Number less than -1
print str$(B_Number)
print chr$("X ")
.ElseIf (B_Number == -1) ; if B_Number equals to -1
print chr$("- X ")
.ElseIf (B_Number == 1) ; if B_Number equals to 1
print chr$("+ X ")
.ElseIf (B_Number > 1) ; if B_Number greater than 1
print chr$("+ ")
print str$(B_Number)
print chr$("X ")
.EndIf
.If (C_Number < SDWord Ptr - 1) ; if C_Number less than -1
print str$(C_Number)
.ElseIf (C_Number == -1) ; if C_Number equals to -1
print chr$("- ")
print chr$("1")
.ElseIf (C_Number > 0) ; if C_Number greater than 0
print chr$("+ ")
print str$(C_Number)
.EndIf
print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
; outputted to the screen
print chr$(" X = ")
print Addr signedRoot1 ; print signedRoot1 string array
print chr$(13, 10)
print chr$(" 1 ", 13, 10)
print chr$(" X = ")
print Addr signedRoot2 ; print signedRoot2 string array
print chr$(13, 10)
print chr$(" 2 ", 13, 10)
print chr$(13, 10)
.ElseIf (squareRootNumber <= SDWord Ptr - 1) ; if squareRootNumber less than or
; equal to -1
print chr$(13, 10)
print chr$("There are no real solutions for the quadratic equation : ")
; The following if else statements output the format of the quadratic
; equation
.If (A_Number == -1) ; if A_Number equals to -1
print chr$("-X^2 ")
.ElseIf (A_Number == 1) ; if A_Number equals to 1
print chr$("X^2 ")
.ElseIf ((A_Number > 1) || (A_Number < SDWord Ptr - 1)) ; if A_Number greater
; than 1 OR A_Number less than -1
print str$(A_Number)
print chr$("X^2 ")
.EndIf
.If (B_Number < SDWord Ptr - 1) ; if B_Number less than -1
print str$(B_Number)
print chr$("X ")
.ElseIf (B_Number == -1) ; if B_Number equals to -1
print chr$("- X ")
.ElseIf (B_Number == 1) ; if B_Number equals to 1
print chr$("+ X ")
.ElseIf (B_Number > 1) ; if B_Number greater than 1
print chr$("+ ")
print str$(B_Number)
print chr$("X ")
.EndIf
.If (C_Number < SDWord Ptr - 1) ; if C_Number less than -1
print str$(C_Number)
.ElseIf (C_Number == -1) ; if C_Number equals to -1
print chr$("- ")
print chr$("1")
.ElseIf (C_Number > 0) ; if C_Number greater than 0
print chr$("+ ")
print str$(C_Number)
.EndIf
print chr$(" !", 13, 10, 13, 10) ; ! will be outputted along with two
; carriage return line feeds to the screen
.EndIf
.ElseIf
print chr$(13, 10)
print chr$("Error, Division by zero!", 13, 10, 13, 10) ; if A_Number == 0
.EndIf
Ret
calculateQuadraticRoots EndP
End start
I want to know if there is a real or floating point square root function?
Are there functions for the regular arithmetic functions such addition, subtraction, multiplication and division using real or floating point numbers?
If yes how do I declare them and use them?
etow,
Yes, there are floating-point instructions that do all of that.
Take a look at Simply FPU (http://www.ray.masmcode.com/tutorial/index.html). It has everything you ever wanted to know about using the FPU.
Here (http://www.masm32.com/board/index.php?topic=7849.0) is a program I posted that makes extensive use of FPU.
Quote from: etow on February 02, 2008, 12:26:07 AM
I want to know if there is a real or floating point square root function?
Are there functions for the regular arithmetic functions such addition, subtraction, multiplication and division using real or floating point numbers?
If yes how do I declare them and use them?
Hi etow,
1. Here an example to Add the variable
RealNumberX with
RealNumberY.
The result goes to variable
RealNumberZ. I have no experience in using
this functions, but i think it is correct.
2. Read the file fpulib in the folder
masm32\help 3. See all ASM files - other functions - in the folder
masm32\fpulib 4. Try and show to us your results.
;**** we should include this files *****
include \masm32\fpulib\fpu.inc
includelib \masm32\fpulib\fpu.lib
;***************************************
;.....................................................................
.data
RealNumberX REAL10 5623.56786 ; save it in 10 bytes = 80 bits
RealNumberY REAL10 -123.5678 ; save it in 10 bytes = "
RealNumberZ REAL10 ? ; result in 10 bytes = "
;......................................................................
.code
invoke FpuAdd, offset RealNumberX, offset RealNumberY, offset RealNumberZ,
SRC1_REAL or SRC2_REAL
Good work !
RuiLoureiro
To do the same thing directly using the FPU:
.DATA
RealNumberX REAL10 5623.56786 ; save it in 10 bytes = 80 bits
RealNumberY REAL10 -123.5678 ; save it in 10 bytes = "
RealNumberZ REAL10 0.0 ; result in 10 bytes = "
.CODE
start:
finit ; Set the FPU to default settings, 64-bit precision,
; round to nearest etc.
fld RealNumberX ; Load RealNumberX to ST(0).
fld RealNumberY ; Load RealNumberY to ST(0), RealNumberX is now in ST(1).
fadd ; Add ST(0) to ST(1), store the result in ST(1),
; pop the stack, the result is now in ST(0).
fstp RealNumberZ ; Store ST(0) to RealNumberZ and pop the stack.
Hi Greg,
Good. Thank you !
By the way, after finit , fld RealNumberX ; Load RealNumberX to ST(0)
and ST(0) is the register number 7 ( status word bits 13- 11 ) no ?
fadd ; Add ST(0) to ST(1), store the result in ST(1),
; pop the stack ?, the result is now in ST(0).
I know faddp ; add real and pop. fadd does the same thing ?
Thank you Greg.
Rui
Hi
My updated code below:
--------------------------------------------------------------------------
.686 ; create 32 bit code
.Model flat, StdCall ;32 bit memory model
Option CaseMap :none ; case sensitive
;The MASM32 Runtime Library include file.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\masm32rt.inc
.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
calculateQuadraticRoots Proto:Real8, :Real8, :Real8
Main Proc
Local WantContinue:DWord
Local NumberA:Real8
Local NumberB:Real8
Local NumberC:Real8
; 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 to 0 to start while loop
.While ((WantContinue >= 0) && (WantContinue < -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 an integer value for Number A : ")
Invoke InputR10, Addr NumberA
print chr$("Enter an integer value for Number B : ")
Invoke InputR10, Addr NumberB
print chr$("Enter an integer value for Number C : ")
Invoke InputR10, Addr NumberC
Invoke calculateQuadraticRoots, NumberA, NumberB, NumberC
print chr$(13, 10)
Mov WantContinue, sval(input("Enter -1 to quit program : "))
print chr$(13, 10)
.EndW
Ret
Main EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<< calculateQuadraticRoots procedure will calculate two real roots <<
;<< of a quadratic equation by receiving three coefficients from <<
;<< user as input <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateQuadraticRoots Proc A_Number:Real8, B_Number:Real8, C_Number:Real8
Local squareRootNumber:Real8
Local negativeB:Real8
Local resultOfSquareRoot:Real8
Local denominator:Real8
Local signedRoot1:Real8
Local signedRoot2:Real8
; squareRootNumber is the square root part of the quadratic formula
; negativeB is the negation of b of the quadratic formula
; resultOfSquareRoot is the result after getting square root of number
; of the quadratic formula
; signedRoot1 and signedRoot2 are the string arrays which are the two X solutions
; to the quadratic formula
; numerator1 and numerator2 are the numerator part of the quadratic formula
; that has two solutions
; denominator is the denominator of the quadratic formula
; Eax, Ebx, Ecx, Edx, Esi, Edi are registers
; Quadratic Formula: x = (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)
.If (A_Number != 0.0) ; if A_Number is not equal to zero
Fld (A_Number) ; st(0) = A_Number
Fld (C_Number) ; st(0) = C_Number , st(1) = A_Number
Fmulp St(1), St ; st(1) = st(1) * st(0) = A_Number * C_Number
Fld (-4.0) ; st(0) = -4.0 , st(1) = A_Number * C_Number
Fmulp St(1), St ; st(1) = st(1) * st(0) = A_Number * C_Number * -4.0
Fld (B_Number) ; st(0) = B_Number , st(1) = A_Number * C_Number * -4.0
Fmul St, St ; st(0) = st(0) * st(0) = B_Number * B_Number
Faddp St(1), St ; st(1) = st(1) + st(0)
; = A_Number * C_Number * -4.0 + B_Number * B_Number
Fstp squareRootNumber ; squareRootNumber = St(1) + St(0)
.If (squareRootNumber > SDWord Ptr - 1.0) ; if squareRootNumber > -1.0
Fsqrt ; Sqrt st(0)
Fstp resultOfSquareRoot ; resultOfSquareRoot = sqrt st(0)
Fld (B_Number) ; st(0) = B_Number
Fchs ; st(0) = -B_Number
Fstp negativeB ; negativeB = st(0)
Fld negativeB ; st(0) = negativeB
Fld resultOfSquareRoot ; st(0) = resultOfSquareRoot , st(1) = negativeB
Faddp St(1), St ; st(1) = st(1) + st(0) = negativeB + resultOfSquareRoot
Fstp numerator1 ; numerator1 = st(0)
Fld (A_Number) ; st(0) = A_Number
Fld (2.0) ; st(0) = 2.0 , st(1) = A_Number
Fmulp St(1), St ; st(1) = st(1) * st(0) = A_Number * 2.0
Fstp denominator ; denominator = st(0)
Fld (numerator1) ; st(0) = numerator1
Fld (denominator) ; st(0) = denominator , st(1) numerator1
Fdivp St(1), St ; st(1) = st(1) / st(0) = numerator1 / denominator
Fstp signedRoot1 ; signedRoot1 = st(1) = numerator1 / denominator
Fld negativeB ; st(0) = negativeB
Fld resultOfSquareRoot ; st(0) = resultOfSquareRoot , st(1) = negativeB
Fchs ; st(0) = -resultOfSquareRoot
Faddp St(1), St ; st(1) = st(1) + st(0) = negativeB + -resultOfSquareRoot
Fld denominator ; st(0) = denominator , st(1) = negativeB + resultOfSquareRoot
Fdivp St(1), St ; st(1) = st(1) / st(0) = (negativeB + resultOfSquareRoot) / denominator
Fstp signedRoot2 ; signedRoot2 = st(1)
print chr$(13, 10) ; a carriage return line feed will be outputted to the
; screen
print chr$(" Solutions for quadratic equation : ")
; The following if else statements output the format of the quadratic
; equation
.If (A_Number == -1.0) ; if A_Number equals to -1.0
print chr$("-X^2 ")
.ElseIf (A_Number == 1.0) ; if A_Number equals to 1.0
print chr$("X^2 ")
.ElseIf ((A_Number > 1.0) || (A_Number < SDWord Ptr - 1.0))
; if A_Number greater than 1.0 Or A_Number less than - 1.0
print real8$ (A_Number)
print chr$("X^2 ")
.EndIf
.If (B_Number < SDWord Ptr - 1.0) ; if B_Number less than -1.0
print real8$ (B_Number)
print chr$("X ")
.ElseIf (B_Number == -1.0) ; if B_Number equals to -1.0
print chr$("- X ")
.ElseIf (B_Number == 1.0) ; if B_Number equals to 1.0
print chr$("+ X ")
.ElseIf (B_Number > 1.0) ; if B_Number greater than 1.0
print chr$("+ ")
print real8$ (B_Number)
print chr$("X ")
.EndIf
.If (C_Number < SDWord Ptr - 1.0) ; if C_Number less than -1.0
print real8$ (C_Number)
.ElseIf (C_Number == -1.0) ; if C_Number equals to -1.0
print chr$("- ")
print chr$("1")
.ElseIf (C_Number > 0.0) ; if C_Number greater than 0.0
print chr$("+ ")
print real8$ (C_Number)
.EndIf
print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
; outputted to the screen
print chr$(" X = ")
print real8$ (signedRoot1) ; print signedRoot1 string array
print chr$(13, 10)
print chr$(" 1 ", 13, 10)
print chr$(" X = ")
print real8$ (signedRoot2) ; print signedRoot2 string array
print chr$(13, 10)
print chr$(" 2 ", 13, 10)
print chr$(13, 10)
.ElseIf (squareRootNumber <= SDWord Ptr - 1.0) ;
; 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 if else statements output the format of the quadratic
; equation
.If (A_Number == -1.0) ; if A_Number equals to -1.0
print chr$("-X^2 ")
.ElseIf (A_Number == 1.0) ; if A_Number equals to 1.0
print chr$("X^2 ")
.ElseIf ((A_Number > 1.0) || (A_Number < SDWord Ptr - 1.0))
; if A_Number greater than 1.0 OR A_Number less than -1.0
print real8$ (A_Number)
print chr$("X^2 ")
.EndIf
.If (B_Number < SDWord Ptr - 1.0) ; if B_Number less than -1.0
print real8$ (B_Number)
print chr$("X ")
.ElseIf (B_Number == -1.0) ; if B_Number equals to -1.0
print chr$("- X ")
.ElseIf (B_Number == 1.0) ; if B_Number equals to 1.0
print chr$("+ X ")
.ElseIf (B_Number > 1.0) ; if B_Number greater than 1.0
print chr$("+ ")
print real8$ (B_Number)
print chr$("X ")
.EndIf
.If (C_Number < SDWord Ptr - 1.0) ; if C_Number less than -1.0
print real8$ (C_Number)
.ElseIf (C_Number == -1.0) ; if C_Number equals to -1.0
print chr$("- ")
print chr$("1")
.ElseIf (C_Number > 0.0) ; if C_Number greater than 0.0
print chr$("+ ")
print real8$ (C_Number)
.EndIf
print chr$(" !", 13, 10, 13, 10) ; ! will be outputted along with two
; carriage return line feeds to the screen
.EndIf
.ElseIf
print chr$(13, 10)
print chr$("Error, Division by zero!", 13, 10, 13, 10) ; if A_Number == 0
.EndIf
Ret
calculateQuadraticRoots EndP
End start
----------------------------------------------------------------------------------------
The following are my debug error messages:
============== QuadraticSolutions - Debug ==============
Assembling: Module1
Module1.asm(2) : warning A4011: multiple .MODEL directives found : .MODEL ignored
\masm32\include\masm32rt.inc(33) : warning A4011: multiple .MODEL directives found : .MODEL ignored
------------------------------------------
WARNING Duplicate include file windows.inc
------------------------------------------
-----------------------------------------
WARNING Duplicate include file user32.inc
-----------------------------------------
-----------------------------------------
WARNING Duplicate include file kernel32.inc
-----------------------------------------
Module1.asm(91) : error A2050: real or BCD number not allowed
Module1.asm(96) : error A2009: syntax error in expression
Module1.asm(104) : error A2009: syntax error in expression
Module1.asm(112) : error A2050: real or BCD number not allowed
Module1.asm(133) : error A2050: real or BCD number not allowed
Module1.asm(135) : error A2050: real or BCD number not allowed
Module1.asm(137) : error A2050: real or BCD number not allowed
Module1.asm(137) : error A2009: syntax error in expression
Module1.asm(143) : error A2009: syntax error in expression
Module1.asm(146) : error A2050: real or BCD number not allowed
Module1.asm(148) : error A2050: real or BCD number not allowed
Module1.asm(150) : error A2050: real or BCD number not allowed
Module1.asm(156) : error A2009: syntax error in expression
Module1.asm(158) : error A2050: real or BCD number not allowed
Module1.asm(161) : error A2050: real or BCD number not allowed
Module1.asm(178) : error A2009: syntax error in expression
Module1.asm(186) : error A2050: real or BCD number not allowed
Module1.asm(188) : error A2050: real or BCD number not allowed
Module1.asm(190) : error A2050: real or BCD number not allowed
Module1.asm(190) : error A2009: syntax error in expression
Module1.asm(196) : error A2009: syntax error in expression
Module1.asm(199) : error A2050: real or BCD number not allowed
Module1.asm(201) : error A2050: real or BCD number not allowed
Module1.asm(203) : error A2050: real or BCD number not allowed
Module1.asm(209) : error A2009: syntax error in expression
Module1.asm(211) : error A2050: real or BCD number not allowed
Module1.asm(214) : error A2050: real or BCD number not allowed
Errors ocurred.
--------------------------------------------------------------------
How do I solve these error messages with comparision run time operators related to integers that can be used for floating point or real numbers and floating point instructions.
Please help me.
Thanks
etow,
You need to go back and read what people have told you, more than once, about include files. Take a look at what 'masm32rt.inc' contains. Whatever it contains does not need to be included in your code again.
You cannot use real numbers with the MASM high-level directives like .IF. To compare real numbers you must use an FPU instruction like FCOM. Read about FCOM in SimplyFPU, there is example code too.
Hi etow,
1. It is too hard to follow, yet.
2. I think you cannot load constants like *** fld -4 ***, *** fld 2 ****
3. To calculate 2a: fld A_Number
fld st(0) ; copy to new st(0)
fadd ; st0= 2a
4. To test b^2-4ac:
ftst
fwait
fstsw ax
5. Why not to use global variables ?
.DATA
Number4 REAL10 4.0 then fld Number4
6. Cannot you divide calculateQuadraticRoots in such a way that it only calculate
signedRoot1 and signedRoot2 ? It can exit with EAX = 0 meaning OK, EAX=1 -> error
EAX= 2 ... etc. Put the other things in another proc if you can
7. Cannot you test A_Number before calling calculateQuadraticRoots ? You dont call if
it is 0.
8. You can calculate Root1 and Root2 without using local variables. FPU has 8 registers and
you can use it. Think about this. How to use them better
RuiLoureiro
Quote from: RuiLoureiro2. I think you cannot load constants like *** fld -4 ***, *** fld 2 ****
That's right, you can't.
There are some MASM32 macros for doing this called FP4, FP8 and FP10. Also see the fld4, fld8 and fld10 macros.
fld FP10(5.5)
fld FP10(2.5)
fld10 5.5
fld10 2.5
Some macros I wrote for comparing real numbers:
; ====================================
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
; ====================================
Usage:
.IF isgreater(r1, r2)
...
.ENDIF
Hi Greg,
for example in one of your macros isgreater than what is REQ data type means for r1 and r2
Can you use for example do this?,
.If isgreater(st(0),-1.0)
....
.Endif
hi Greg,
Can you do this,
.If isgreater(Real10 Ptr [Eax],-1.0)
....
.Endif
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
Number2 Real10 2.0
NumberNegative4 Real10 - 4.0
.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
; ====================================
calculateQuadraticRoots Proto:Ptr Real10, Ptr Real10, Ptr Real10
printFormat Proto:Ptr Real10, Ptr Real10, Ptr Real10
Main Proc
Local WantContinue:DWord
Local NumberA:Real10
Local NumberB:Real10
Local NumberC:Real10
; 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 to 0 to start while loop
.While ((WantContinue >= 0) && (WantContinue < -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 an integer value for Number A : ")
Invoke InputR10, Addr NumberA
print chr$("Enter an integer value for Number B : ")
Invoke InputR10, Addr NumberB
print chr$("Enter an integer value for Number C : ")
Invoke InputR10, Addr NumberC
.If isnotequal(Addr NumberA, 0.0) ; if NumberA != 0.0
Invoke calculateQuadraticRoots, Addr NumberA, Addr NumberB, Addr NumberC
print chr$(13, 10)
.ElseIf isequal(Addr NumberA, 0.0)
print chr$(13, 10)
print chr$("Error, Division by zero!", 13, 10, 13, 10) ; if NumberA == 0
.EndIf
Mov WantContinue, sval(input("Enter -1 to quit program : "))
print chr$(13, 10)
.EndW
Ret
Main EndP
printFormat Proc A_Number:Ptr Real10, B_Number:Ptr Real10, C_Number:Ptr Real10
Mov Eax, A_Number
Mov Ebx, B_Number
Mov Ecx, C_Number
.If isequal(Real10 Ptr [Eax], -1.0)
; if A_Number equals to -1.0
print chr$("-X^2 ")
.ElseIf isequal(Real10 Ptr [Eax], 1.0)
; if A_Number equals to 1.0
print chr$("X^2 ")
.ElseIf (isgreater(Real10 Ptr [Eax], 1.0) || islessthan (Real10 Ptr [Eax, -1.0))
; if A_Number greater than 1.0 Or A_Number less than - 1.0
print real10$ (A_Number)
print chr$("X^2 ")
.EndIf
.If isless(Real10 Ptr [Ebx], -1.0)
; if B_Number less than -1.0
print real10$ (B_Number)
print chr$("X ")
.ElseIf isequal(Real10 Ptr [Ebx], -1.0)
; if B_Number equals to -1.0
print chr$("- X ")
.ElseIf isequal(Real10 Ptr [Ebx], 1.0)
; if B_Number equals to 1.0
print chr$("+ X ")
.ElseIf isgreater(Real10 Ptr [Ebx], 1.0)
; if B_Number greater than 1.0
print chr$("+ ")
print real10$ (B_Number)
print chr$("X ")
.EndIf
.If isless(Real10 Ptr [Ecx], -1.0)
; if C_Number less than -1.0
print real10$ (C_Number)
.ElseIf isequal(Real10 Ptr [Ecx], -1.0)
; if C_Number equals to -1.0
print chr$("- ")
print chr$("1")
.ElseIf isgreater(Real10 Ptr [Ecx], 0.0)
; if C_Number greater than 0.0
print chr$("+ ")
print real10$ (C_Number)
.EndIf
Ret
printFormat EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<< calculateQuadraticRoots procedure will calculate two real roots <<
;<< of a quadratic equation by receiving three coefficients from <<
;<< user as input <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateQuadraticRoots Proc A_Number:Ptr Real10, B_Number:Ptr Real10, C_Number:Ptr Real10
Local squareRootNumber:Real10
Local negativeB:Real10
Local resultOfSquareRoot:Real10
Local numerator1:Real10
Local denominator:Real10
Local signedRoot1:Real10
Local signedRoot2:Real10
; squareRootNumber is the square root part of the quadratic formula
; negativeB is the negation of b of the quadratic formula
; resultOfSquareRoot is the result after getting square root of number
; of the quadratic formula
; signedRoot1 and signedRoot2 are the string arrays which are the two X solutions
; to the quadratic formula
; numerator1 and numerator2 are the numerator part of the quadratic formula
; that has two solutions
; denominator is the denominator of the quadratic formula
; Eax, Ebx, Ecx, Edx are registers
; St(i) are Fpu registers
; Quadratic Formula: x = (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)
Mov Eax, A_Number
Mov Ebx, B_Number
Mov Ecx, C_Number
Fld Real10 Ptr [Eax] ; st(0) = A_Number
Fld Real10 Ptr [Ecx] ; st(0) = C_Number , st(1) = A_Number
Fmulp St(1), St ; st(1) = st(1) * st(0) = A_Number * C_Number
Fld (NumberNegative4) ; st(0) = -4.0 , st(1) = A_Number * C_Number
Fmulp St(1), St ; st(1) = st(1) * st(0) = A_Number * C_Number * -4.0
Fld Real10 Ptr [Ebx] ; st(0) = B_Number , st(1) = A_Number * C_Number * -4.0
Fmul St, St ; st(0) = st(0) * st(0) = B_Number * B_Number
Faddp St(1), St ; st(1) = st(1) + st(0)
; = A_Number * C_Number * -4.0 + B_Number * B_Number
Fstp squareRootNumber ; squareRootNumber = St(1) + St(0)
Fld squareRootNumber ; st(0) = squareRootNumber
.If isgreater(squareRootNumber, -1.0)
; if squareRootNumber greater than -1.0
Fsqrt ; Sqrt st(0)
Fstp resultOfSquareRoot ; resultOfSquareRoot = sqrt st(0)
Fld Real10 Ptr [Ebx] ; st(0) = B_Number
Fchs ; st(0) = -B_Number
Fstp negativeB ; negativeB = st(0)
Fld negativeB ; st(0) = negativeB
Fld resultOfSquareRoot ; st(0) = resultOfSquareRoot , st(1) = negativeB
Faddp St(1), St ; st(1) = st(1) + st(0) = negativeB + resultOfSquareRoot
Fstp numerator1 ; numerator1 = st(0)
Fld Real10 Ptr [Eax] ; st(0) = A_Number
Fld (Number2) ; st(0) = 2.0 , st(1) = A_Number
Fmulp St(1), St ; st(1) = st(1) * st(0) = A_Number * 2.0
Fstp denominator ; denominator = st(0)
Fld (numerator1) ; st(0) = numerator1
Fld (denominator) ; st(0) = denominator , st(1) numerator1
Fdivp St(1), St ; st(1) = st(1) / st(0) = numerator1 / denominator
Fstp signedRoot1 ; signedRoot1 = st(1) = numerator1 / denominator
Ffree St(0)
Fld negativeB ; st(0) = negativeB
Fld resultOfSquareRoot ; st(0) = resultOfSquareRoot , st(1) = negativeB
Fchs ; st(0) = -resultOfSquareRoot
Faddp St(1), St ; st(1) = st(1) + st(0) = negativeB + -resultOfSquareRoot
Fld denominator ; st(0) = denominator , st(1) = negativeB + resultOfSquareRoot
Fdivp St(1), St ; st(1) = st(1) / st(0) = (negativeB + resultOfSquareRoot) / denominator
Fstp signedRoot2 ; signedRoot2 = st(1)
print chr$(13, 10) ; a carriage return line feed will be outputted to the
; screen
print chr$(" Solutions for quadratic equation : ")
; The following statement call output format procedure of the quadratic
; equation
Invoke printFormat, Addr A_Number, Addr B_Number, Addr C_Number
print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
; outputted to the screen
print chr$(" X = ")
print real10$ (signedRoot1) ; print signedRoot1 string array
print chr$(13, 10)
print chr$(" 1 ", 13, 10)
print chr$(" X = ")
print real10$ (signedRoot2) ; print signedRoot2 string array
print chr$(13, 10)
print chr$(" 2 ", 13, 10)
print chr$(13, 10)
.ElseIf islessequal(squareRootNumber, -1.0)
; 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 printFormat, Addr A_Number, Addr B_Number, Addr 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
-------------------------------------------------------------------
Here are my debugger error messages below:
============== QuadraticSolutions - Debug ==============
Module1.asm(217) : error A2008: syntax error : ptr
Module1.asm(218) : error A2008: syntax error : ptr
Module1.asm(244) : error A2008: syntax error : Addr
isnotequal(4): Macro Called From
Module1.asm(244): Include File
Module1.asm(247) : error A2008: syntax error : Addr
isequal(4): Macro Called From
Module1.asm(247): Include File
Module1.asm(268) : error A2008: syntax error : ,
-------------------------
real10$ - requires REAL10
-------------------------
-------------------------
real10$ - requires REAL10
-------------------------
-------------------------
real10$ - requires REAL10
-------------------------
-------------------------
real10$ - requires REAL10
-------------------------
-------------------------
real10$ - requires REAL10
-------------------------
Module1.asm(243) : error A2050: real or BCD number not allowed
isnotequal(3): Macro Called From
Module1.asm(243): Include File
Module1.asm(246) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
Module1.asm(246): Include File
Module1.asm(261) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
Module1.asm(261): Include File
Module1.asm(264) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
Module1.asm(264): Include File
Module1.asm(267) : error A2050: real or BCD number not allowed
isgreater(3): Macro Called From
Module1.asm(267): Include File
Module1.asm(273) : error A2050: real or BCD number not allowed
isless(3): Macro Called From
Module1.asm(273): Include File
Module1.asm(277) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
Module1.asm(277): Include File
Module1.asm(280) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
Module1.asm(280): Include File
Module1.asm(283) : error A2050: real or BCD number not allowed
isgreater(3): Macro Called From
Module1.asm(283): Include File
Module1.asm(290) : error A2050: real or BCD number not allowed
isless(3): Macro Called From
Module1.asm(290): Include File
Module1.asm(293) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
Module1.asm(293): Include File
Module1.asm(297) : error A2050: real or BCD number not allowed
isgreater(3): Macro Called From
Module1.asm(297): Include File
Module1.asm(352) : error A2050: real or BCD number not allowed
isgreater(3): Macro Called From
Module1.asm(352): Include File
Module1.asm(402) : error A2050: real or BCD number not allowed
islessequal(3): Macro Called From
Module1.asm(402): Include File
Module1.asm(270) : error A2052: forced error
real10$(14): Macro Called From
print(0): Macro Called From
Module1.asm(270): Include File
Module1.asm(276) : error A2052: forced error
real10$(12): Macro Called From
print(0): Macro Called From
Module1.asm(276): Include File
Module1.asm(287) : error A2052: forced error
real10$(12): Macro Called From
print(0): Macro Called From
Module1.asm(287): Include File
Module1.asm(293) : error A2052: forced error
real10$(12): Macro Called From
print(0): Macro Called From
Module1.asm(293): Include File
Module1.asm(301) : error A2052: forced error
real10$(12): Macro Called From
print(0): Macro Called From
Module1.asm(301): Include File
Errors ocurred.
.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
Number2 Real10 2.0
NumberNegative4 Real10 - 4.0
.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
; ====================================
calculateQuadraticRoots Proto:Ptr Real10, Ptr Real10, Ptr Real10
printFormat Proto:Ptr Real10, Ptr Real10, Ptr Real10
Main Proc
Local WantContinue:DWord
Local NumberA:Real10
Local NumberB:Real10
Local NumberC:Real10
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 to 0 to start while loop
.While ((WantContinue >= 0) && (WantContinue < -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 an integer value for Number A : ")
Invoke InputR10, Addr NumberA
print chr$("Enter an integer value for Number B : ")
Invoke InputR10, Addr NumberB
print chr$("Enter an integer value for Number C : ")
Invoke InputR10, Addr NumberC
.If isnotequal(Addr NumberA, 0.0) ; if NumberA != 0.0
Invoke calculateQuadraticRoots, Addr NumberA, Addr NumberB, Addr NumberC
print chr$(13, 10)
.ElseIf isequal(Addr NumberA, 0.0) ; 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)
Mov counter, 0
.While counter <= 8
Ffree St (counter)
Inc counter
.EndW
.EndW
Ret
Main EndP
printFormat Proc A_Number:Ptr Real10, B_Number:Ptr Real10, C_Number:Ptr Real10
Mov Eax, A_Number
Mov Ebx, B_Number
Mov Ecx, C_Number
Fld Real10 Ptr [Eax]
.If isequal(St(0), -1.0)
; if A_Number equals to -1.0
print chr$("-X^2 ")
.ElseIf isequal(St(0), 1.0)
; if A_Number equals to 1.0
print chr$("X^2 ")
.ElseIf (isgreater(St(0), 1.0) || islessthan (St(0), -1.0))
; if A_Number greater than 1.0 Or A_Number less than - 1.0
print real10$ (A_Number)
print chr$("X^2 ")
.EndIf
Fld Real10 Ptr [Ebx]
.If isless(St(0), -1.0)
; if B_Number less than -1.0
print real10$ (B_Number)
print chr$("X ")
.ElseIf isequal(St(0), -1.0)
; if B_Number equals to -1.0
print chr$("- X ")
.ElseIf isequal(St(0), 1.0)
; if B_Number equals to 1.0
print chr$("+ X ")
.ElseIf isgreater(St(0), 1.0)
; if B_Number greater than 1.0
print chr$("+ ")
print real10$ (B_Number)
print chr$("X ")
.EndIf
Fld Real10 Ptr [Ecx]
.If isless(St(0), -1.0)
; if C_Number less than -1.0
print real10$ (C_Number)
.ElseIf isequal(St(0), -1.0)
; if C_Number equals to -1.0
print chr$("- ")
print chr$("1")
.ElseIf isgreater(St(0), 0.0)
; if C_Number greater than 0.0
print chr$("+ ")
print real10$ (C_Number)
.EndIf
Ret
printFormat EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<< calculateQuadraticRoots procedure will calculate two real roots <<
;<< of a quadratic equation by receiving three coefficients from <<
;<< user as input <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateQuadraticRoots Proc A_Number:Ptr Real10, B_Number:Ptr Real10, C_Number:Ptr Real10
Local squareRootNumber:Real10
Local negativeB:Real10
Local resultOfSquareRoot:Real10
Local numerator1:Real10
Local denominator:Real10
Local signedRoot1:Real10
Local signedRoot2:Real10
; squareRootNumber is the square root part of the quadratic formula
; negativeB is the negation of b of the quadratic formula
; resultOfSquareRoot is the result after getting square root of number
; of the quadratic formula
; signedRoot1 and signedRoot2 are the string arrays which are the two X solutions
; to the quadratic formula
; numerator1 is the numerator part of the quadratic formula
; that has two solutions
; denominator is the denominator of the quadratic formula
; Eax, Ebx, Ecx, Edx are registers
; St(i) are Fpu registers
; Quadratic Formula: x = (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)
Mov Eax, A_Number
Mov Ebx, B_Number
Mov Ecx, C_Number
Finit
Fld Real10 Ptr [Eax] ; st(0) = A_Number
Fld Real10 Ptr [Ecx] ; st(0) = C_Number , st(1) = A_Number
Fmulp St(1), St ; st(1) = st(1) * st(0)
; = A_Number * C_Number
Fld (NumberNegative4) ; st(0) = -4.0 , st(1) = A_Number * C_Number
Fmulp St(1), St ; st(1) = st(1) * st(0)
; = A_Number * C_Number * -4.0
Fld Real10 Ptr [Ebx] ; st(0) = B_Number , st(1) = A_Number * C_Number * -4.0
Fmul St, St ; st(0) = st(0) * st(0)
; = B_Number * B_Number
Faddp St(1), St ; st(1) = st(1) + st(0)
; = A_Number * C_Number * -4.0 + B_Number * B_Number
Fstp squareRootNumber ; squareRootNumber = St(1) + St(0)
Fld squareRootNumber ; st(0) = squareRootNumber
.If isgreater(squareRootNumber, -1.0)
; if squareRootNumber greater than -1.0
Fsqrt ; Sqrt st(0)
Fstp resultOfSquareRoot ; resultOfSquareRoot = sqrt st(0)
Fld Real10 Ptr [Ebx] ; st(0) = B_Number
Fchs ; st(0) = -B_Number
Fstp negativeB ; negativeB = st(0)
Fld negativeB ; st(0) = negativeB
Fld resultOfSquareRoot ; st(0) = resultOfSquareRoot , st(1) = negativeB
Faddp St(1), St ; st(1) = st(1) + st(0)
; = negativeB + resultOfSquareRoot
Fstp numerator1 ; numerator1 = st(0)
Fld Real10 Ptr [Eax] ; st(0) = A_Number
Fld (Number2) ; st(0) = 2.0 , st(1) = A_Number
Fmulp St(1), St ; st(1) = st(1) * st(0)
; = A_Number * 2.0
Fstp denominator ; denominator = st(0)
Fld (numerator1) ; st(0) = numerator1
Fld (denominator) ; st(0) = denominator , st(1) numerator1
Fdivp St(1), St ; st(1) = st(1) / st(0)
; = numerator1 / denominator
Fstp signedRoot1 ; signedRoot1 = st(1) = numerator1 / denominator
Ffree St(0)
Fld negativeB ; st(0) = negativeB
Fld resultOfSquareRoot ; st(0) = resultOfSquareRoot , st(1) = negativeB
Fchs ; st(0) = -resultOfSquareRoot
Faddp St(1), St ; st(1) = st(1) + st(0)
; = negativeB + -resultOfSquareRoot
Fld denominator ; st(0) = denominator , st(1) = negativeB + -resultOfSquareRoot
Fdivp St(1), St ; st(1) = st(1) / st(0)
; = (negativeB + -resultOfSquareRoot) / denominator
Fstp signedRoot2 ; signedRoot2 = st(1)
print chr$(13, 10) ; a carriage return line feed will be outputted to the
; screen
print chr$(" Solutions for quadratic equation : ")
; The following statement call output format procedure of the quadratic
; equation
Invoke printFormat, Addr A_Number, Addr B_Number, Addr C_Number
print chr$(13, 10, 13, 10) ; two carriage return line feeds will be
; outputted to the screen
print chr$(" X = ")
print real10$ (signedRoot1) ; print signedRoot1 string array
print chr$(13, 10)
print chr$(" 1 ", 13, 10)
print chr$(" X = ")
print real10$ (signedRoot2) ; print signedRoot2 string array
print chr$(13, 10)
print chr$(" 2 ", 13, 10)
print chr$(13, 10)
.ElseIf islessequal(squareRootNumber, -1.0)
; 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 printFormat, Addr A_Number, Addr B_Number, Addr 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
Hi
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
Number2 Real10 2.0
NumberNegative4 Real10 - 4.0
.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 NumberA:Real10
Local NumberB:Real10
Local NumberC:Real10
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 to 0 to start while loop
.While ((WantContinue >= 0) && (WantContinue < -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 value for Number A : ")
Invoke InputR10, Addr NumberA
print chr$("Enter a real value for Number B : ")
Invoke InputR10, Addr NumberB
print chr$("Enter a real value for Number C : ")
Invoke InputR10, Addr NumberC
.If isnotequal(NumberA, 0.0) ; if NumberA != 0.0
Invoke calculateQuadraticRoots, NumberA, NumberB, NumberC
print chr$(13, 10)
.ElseIf isequal(NumberA, 0.0) ; 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)
Mov counter, 0
.While counter <= 8
Ffree St (counter)
Inc counter
.EndW
.EndW
Ret
Main EndP
printQuadraticFormat Proc A_Number:Real10, B_Number:Real10, C_Number:Real10
Mov Eax, A_Number
Mov Ebx, B_Number
Mov Ecx, C_Number
Fld Real10 Ptr [Eax]
.If isequal(St(0), -1.0)
; if A_Number equals to -1.0
print chr$("-X^2 ")
.ElseIf isequal(St(0), 1.0)
; if A_Number equals to 1.0
print chr$("X^2 ")
.ElseIf (isgreater(St(0), 1.0) || isless(St(0), -1.0))
; if A_Number greater than 1.0 Or A_Number less than - 1.0
print real10$ (St(0))
print chr$("X^2 ")
.EndIf
Fld Real10 Ptr [Ebx]
.If isless(St(0), -1.0)
; if B_Number less than -1.0
print real10$ (St(0))
print chr$("X ")
.ElseIf isequal(St(0), -1.0)
; if B_Number equals to -1.0
print chr$("- X ")
.ElseIf isequal(St(0), 1.0)
; if B_Number equals to 1.0
print chr$("+ X ")
.ElseIf isgreater(St(0), 1.0)
; if B_Number greater than 1.0
print chr$("+ ")
print real10$ (St(0))
print chr$("X ")
.EndIf
Fld Real10 Ptr [Ecx]
.If isless(St(0), -1.0)
; if C_Number less than -1.0
print real10$ (St(0))
.ElseIf isequal(St(0), -1.0)
; if C_Number equals to -1.0
print chr$("- ")
print chr$("1")
.ElseIf isgreater(St(0), 0.0)
; if C_Number greater than 0.0
print chr$("+ ")
print real10$ (St(0))
.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
Local squareRootNumber:Real10
Local negativeB:Real10
Local resultOfSquareRoot:Real10
Local numerator1:Real10
Local denominator:Real10
Local signedRoot1:Real10
Local signedRoot2:Real10
; squareRootNumber is the square root part of the quadratic formula
; negativeB is the negation of b of the quadratic formula
; resultOfSquareRoot is the result after getting square root of number
; of the quadratic formula
; signedRoot1 and signedRoot2 are the string arrays which are the two X solutions
; to the quadratic formula
; numerator1 is the numerator part of the quadratic formula
; that has two solutions
; denominator is the denominator of the quadratic formula
; Eax, Ebx, Ecx, Edx are registers
; St(i) are Fpu registers
; Quadratic Formula: x = (-b +/- sqrt(b^2 - 4*a*c)) / (2*a)
Mov Eax, A_Number
Mov Ebx, B_Number
Mov Ecx, C_Number
Finit
Fld Real10 Ptr [Eax] ; st(0) = A_Number
Fld Real10 Ptr [Ecx] ; st(0) = C_Number , st(1) = A_Number
Fmulp St(1), St ; st(1) = st(1) * st(0)
; = A_Number * C_Number
Fld (NumberNegative4) ; st(0) = -4.0 , st(1) = A_Number * C_Number
Fmulp St(1), St ; st(1) = st(1) * st(0)
; = A_Number * C_Number * -4.0
Fld Real10 Ptr [Ebx] ; st(0) = B_Number , st(1) = A_Number * C_Number * -4.0
Fmul St, St ; st(0) = st(0) * st(0)
; = B_Number * B_Number
Faddp St(1), St ; st(1) = st(1) + st(0)
; = A_Number * C_Number * -4.0 + B_Number * B_Number
Fstp squareRootNumber ; squareRootNumber = St(1) + St(0)
Fld squareRootNumber ; st(0) = squareRootNumber
.If isgreater(squareRootNumber, -1.0)
; if squareRootNumber greater than -1.0
Fsqrt ; Sqrt st(0)
Fstp resultOfSquareRoot ; resultOfSquareRoot = sqrt st(0)
Fld Real10 Ptr [Ebx] ; st(0) = B_Number
Fchs ; st(0) = -B_Number
Fstp negativeB ; negativeB = st(0)
Fld negativeB ; st(0) = negativeB
Fld resultOfSquareRoot ; st(0) = resultOfSquareRoot , st(1) = negativeB
Faddp St(1), St ; st(1) = st(1) + st(0)
; = negativeB + resultOfSquareRoot
Fstp numerator1 ; numerator1 = st(0)
Fld Real10 Ptr [Eax] ; st(0) = A_Number
Fld (Number2) ; st(0) = 2.0 , st(1) = A_Number
Fmulp St(1), St ; st(1) = st(1) * st(0)
; = A_Number * 2.0
Fstp denominator ; denominator = st(0)
Fld (numerator1) ; st(0) = numerator1
Fld (denominator) ; st(0) = denominator , st(1) numerator1
Fdivp St(1), St ; st(1) = st(1) / st(0)
; = numerator1 / denominator
Fstp signedRoot1 ; signedRoot1 = st(1) = numerator1 / denominator
Ffree St(0)
Fld negativeB ; st(0) = negativeB
Fld resultOfSquareRoot ; st(0) = resultOfSquareRoot , st(1) = negativeB
Fchs ; st(0) = -resultOfSquareRoot
Faddp St(1), St ; st(1) = st(1) + st(0)
; = negativeB + -resultOfSquareRoot
Fld denominator ; st(0) = denominator , st(1) = negativeB + -resultOfSquareRoot
Fdivp St(1), St ; st(1) = st(1) / st(0)
; = (negativeB + -resultOfSquareRoot) / denominator
Fstp signedRoot2 ; signedRoot2 = st(1)
print chr$(13, 10) ; a carriage return line feed will be outputted to the
; screen
print chr$(" Solutions for quadratic equation : ")
; The following statement call output format procedure of the quadratic
; equation
Mov A_Number, Eax
Mov B_Number, Ebx
Mov C_Number, Ecx
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$ (signedRoot1) ; print signedRoot1 string array
print chr$(13, 10)
print chr$(" 1 ", 13, 10)
print chr$(" X = ")
print real10$ (signedRoot2) ; print signedRoot2 string array
print chr$(13, 10)
print chr$(" 2 ", 13, 10)
print chr$(13, 10)
.ElseIf islessequal(squareRootNumber, -1.0)
; 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
Mov A_Number, Eax
Mov B_Number, Ebx
Mov C_Number, Ecx
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
-------------------------------------------------------------------------------------------
Here are my debugger error messages below:
Module1.asm(215) : error A2008: syntax error : real10
Module1.asm(216) : error A2008: syntax error : real10
Module1.asm(265) : error A2070: invalid instruction operands
Module1.asm(266) : error A2070: invalid instruction operands
Module1.asm(267) : error A2070: invalid instruction operands
Module1.asm(349) : error A2070: invalid instruction operands
Module1.asm(350) : error A2070: invalid instruction operands
Module1.asm(351) : error A2070: invalid instruction operands
Module1.asm(411) : error A2070: invalid instruction operands
Module1.asm(412) : error A2070: invalid instruction operands
Module1.asm(413) : error A2070: invalid instruction operands
Module1.asm(436) : error A2070: invalid instruction operands
Module1.asm(437) : error A2070: invalid instruction operands
Module1.asm(438) : error A2070: invalid instruction operands
Module1.asm(243) : error A2050: real or BCD number not allowed
isnotequal(3): Macro Called From
Module1.asm(243): Include File
Module1.asm(246) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
Module1.asm(246): Include File
Module1.asm(256) : error A2115: invalid coprocessor register
Module1.asm(270) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
Module1.asm(270): Include File
Module1.asm(273) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
Module1.asm(273): Include File
Module1.asm(276) : error A2050: real or BCD number not allowed
isgreater(3): Macro Called From
Module1.asm(276): Include File
Module1.asm(276) : error A2050: real or BCD number not allowed
isless(3): Macro Called From
Module1.asm(276): Include File
Module1.asm(284) : error A2050: real or BCD number not allowed
isless(3): Macro Called From
Module1.asm(284): Include File
Module1.asm(288) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
Module1.asm(288): Include File
Module1.asm(291) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
Module1.asm(291): Include File
Module1.asm(294) : error A2050: real or BCD number not allowed
isgreater(3): Macro Called From
Module1.asm(294): Include File
Module1.asm(303) : error A2050: real or BCD number not allowed
isless(3): Macro Called From
Module1.asm(303): Include File
Module1.asm(306) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
Module1.asm(306): Include File
Module1.asm(310) : error A2050: real or BCD number not allowed
isgreater(3): Macro Called From
Module1.asm(310): Include File
Module1.asm(370) : error A2050: real or BCD number not allowed
isgreater(3): Macro Called From
Module1.asm(370): Include File
Module1.asm(428) : error A2050: real or BCD number not allowed
islessequal(3): Macro Called From
Module1.asm(428): Include File
Errors ocurred.
-----------------------------------------------------------------------------------------------------------------------
I don't understand what these error messages mean. I just know where the error messages occur at. Please help me.
Thanks
Module1.asm(215) : error A2008: syntax error : real10
Module1.asm(216) : error A2008: syntax error : real10
; The correct syntax is Proto :Real10, :Real10, :Real10
Module1.asm(265) : error A2070: invalid instruction operands
Module1.asm(266) : error A2070: invalid instruction operands
Module1.asm(267) : error A2070: invalid instruction operands
Module1.asm(349) : error A2070: invalid instruction operands
Module1.asm(350) : error A2070: invalid instruction operands
Module1.asm(351) : error A2070: invalid instruction operands
Module1.asm(411) : error A2070: invalid instruction operands
Module1.asm(412) : error A2070: invalid instruction operands
Module1.asm(413) : error A2070: invalid instruction operands
Module1.asm(436) : error A2070: invalid instruction operands
Module1.asm(437) : error A2070: invalid instruction operands
Module1.asm(438) : error A2070: invalid instruction operands
; An 80-bit real10 will not fit in a 32-bit register.
Module1.asm(243) : error A2050: real or BCD number not allowed
isnotequal(3): Macro Called From
Module1.asm(243): Include File
Module1.asm(246) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
Module1.asm(246): Include File
Module1.asm(270) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
Module1.asm(270): Include File
Module1.asm(273) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
Module1.asm(273): Include File
Module1.asm(276) : error A2050: real or BCD number not allowed
isgreater(3): Macro Called From
Module1.asm(276): Include File
Module1.asm(276) : error A2050: real or BCD number not allowed
isless(3): Macro Called From
Module1.asm(276): Include File
Module1.asm(284) : error A2050: real or BCD number not allowed
isless(3): Macro Called From
Module1.asm(284): Include File
Module1.asm(288) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
Module1.asm(288): Include File
Module1.asm(291) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
Module1.asm(291): Include File
Module1.asm(294) : error A2050: real or BCD number not allowed
isgreater(3): Macro Called From
Module1.asm(294): Include File
Module1.asm(303) : error A2050: real or BCD number not allowed
isless(3): Macro Called From
Module1.asm(303): Include File
Module1.asm(306) : error A2050: real or BCD number not allowed
isequal(3): Macro Called From
Module1.asm(306): Include File
Module1.asm(310) : error A2050: real or BCD number not allowed
isgreater(3): Macro Called From
Module1.asm(310): Include File
Module1.asm(370) : error A2050: real or BCD number not allowed
isgreater(3): Macro Called From
Module1.asm(370): Include File
Module1.asm(428) : error A2050: real or BCD number not allowed
islessequal(3): Macro Called From
Module1.asm(428): Include File
; The fld instruction in the macros cannot load immediate values.
; One easy way to deal with this would be to create variables
; that contain the necessary values and pass these to the macros:
zero REAL10 0.0
one REAL10 1.0
negone REAL10 -1.0
...
Module1.asm(256) : error A2115: invalid coprocessor register
; The fpu registers must be specified as constants (and there is no st(8)).
; One easy way to deal with this is:
ffree st(0)
ffree st(1)
ffree st(2)
ffree st(3)
ffree st(4)
ffree st(5)
ffree st(6)
ffree st(7)
QuoteCan you use for example do this?
No.
QuoteCan you do this?
No.
Looks like MichaelW answered the rest of your questions.
Come on etow, you have been given everything you need to write this program. You need to go back and read the tutorials and documentation, you're still missing the basics.
To be simple, define A_Number, B_Number and C_Number and the solutions
RootX0 and RootX1 in data segment.
So printFormat and calculateQuadraticRoots dont have input parameters.
They assume the values in that global variables.
calculateQuadraticRoots put the roots in RootX0 and RootX1 for whatever
you need.
In this way you use instructions like *** fld A_Number ***
*** fld B_Number *** and *** fld C_Number ***.
Your InputR10 should get the user's integer values and converte it
to Real10 format A_Number, B_Number and C_Number. Or convert it
to integers NumberA, NumberB and NumberC and then to reals.
Test A_Number against 0.0 before calling calculateQuadraticRoot
If A_Number is 0, the equation is first degree or ... It is not
an Error, Division by zero.
What do you mean with *** A_Number:Ptr Real10 ***. It means the same
as A_Number:DWORD if it is a pointer. All pointers here are 32 bits
.data
;
; All numbers are real numbers
; ----------------------------
A_Number REAL10 1.0 ; Put here the Number a
B_Number REAL10 -1.0 ; Put here the Number b
C_Number REAL10 -12.0 ; Put here the Number c
;..........................
RootX0 REAL10 ?
RootX1 REAL10 ?
;......................................................................
.code
RuiLoureiro
hi
I found the FPU Tutorial. I read it and understand it.
Is there a function or procedure to read floating point numbers already in masm32 version 9 library?
Please reply.
Thanks
Greg's application to me is very complex and confusing to me.
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
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.
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
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
etow,
The sval macro isn't going to work. What's wrong with InputR10? I wrote it and it works fine for me.
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?
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?
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
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
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.
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
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
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
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
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
Hi RuiLoureiro
fld A_Number
fld C_Number
fmul ; ac
add st(0), st(0) ; 2ac
add st(0), st(0) ; 4ac
That is much better than the way I did it. I noticed etow declared constants 0 ; -1 ; 1 ; 2 and -4, so I used the constant 1 that is within the FPU.
That -4 triggered my respons because that is not a -4 in the formula. ((B*B)-(4*A*C)) That negative means subtract the second part from the first part. It is easy to see that it does change the sign of the second part but please complete the second part first before applying that minus sign.
Greatings.
hi RuiLoureiro
I used your example program but got no results when I compiled it and ran it
what is wrong for the 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
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
.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
Two Real10 2.0 ; number to use to get the denominator in the quadratic formula
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
NegativeFour Real10 - 4.0 ; number to use to get a square root number 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
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
Invoke calculateQuadraticRoots
print chr$(13, 10)
; print chr$(13, 10)
; print chr$("Error, Division by Zero!", 13, 10, 13, 10)
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
.If isequal (NumberA, NegativeOne)
; if NumberA equals to -1.0
print chr$("-1.0 X^2 ")
.ElseIf isequal (NumberA, One)
; if NumberA equals to 1.0
print chr$("1.0 X^2 ")
.ElseIf (isgreater (NumberA, One) || isless (NumberA, NegativeOne))
; if NumberA greater than 1.0 Or A_Number less than - 1.0
Invoke FpuFLtoA, 0, 5, Addr NumberA, SRC1_FPU Or SRC2_DIMM
print chr$(" X^2 ")
.EndIf
.If isless (NumberB, NegativeOne)
; if NumberB less than -1.0
Invoke FpuFLtoA, 0, 5, Addr NumberB, SRC1_FPU Or SRC2_DIMM
print chr$(" X ")
.ElseIf isequal (NumberB, NegativeOne)
; if NumberB equals to -1.0
print chr$("-1.0 X ")
.ElseIf isequal (NumberB, One)
; if NumberB equals to 1.0
print chr$("+ 1.0 X ")
.ElseIf isgreater (NumberB, One)
; if NumberB greater than 1.0
print chr$("+ ")
Invoke FpuFLtoA, 0, 5, Addr NumberB, SRC1_FPU Or SRC2_DIMM
print chr$(" X ")
.EndIf
.If isless (NumberC, NegativeOne)
; if NumberC less than -1.0
Invoke FpuFLtoA, 0, 5, Addr NumberC, SRC1_FPU Or SRC2_DIMM
.ElseIf isequal (NumberC, NegativeOne)
; if NumberC equals to -1.0
print chr$("-1.0 ")
.ElseIf isgreater (NumberC, Zero)
; if NumberC greater than 0.0
print chr$("+ ")
Invoke FpuFLtoA, 0, 5, Addr NumberC, SRC1_FPU Or SRC2_DIMM
.EndIf
Ret
printQuadraticFormat EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<< calculateXRoots procedure will calculate the two real roots in the quadratic <<
;<< formula <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateXRoots 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 solutionX1:Real10
Local solutionX2:Real10
Lea Ebx, NumB2
Invoke FpuMul, pNumB, pNumB, Ebx, SRC1_REAL Or SRC2_REAL
Or Eax, Eax
Jz _rRealRoots
Lea Ecx, Num4AC
Invoke FpuMul, pNumA, pNumC, Ecx, SRC1_REAL Or SRC2_REAL
Or Eax, Eax
Jz _rRealRoots
;
Invoke FpuMul, Ecx, Offset NegativeFour, 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
; if NumB2_4AC >= 0
;---------------------
Invoke FpuComp, Edx, Offset Zero, 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, solutionX1
Invoke FpuSub, Ebx, pNumB, Ecx, SRC1_REAL Or SRC2_REAL
Or Eax, Eax
Jz _rRealRoots
Lea Edx, solutionX2
Invoke FpuAdd, Ebx, pNumB, Edx, SRC1_REAL Or SRC2_REAL
Or Eax, Eax
Jz _rRealRoots
Lea Ebx, Num2A
Invoke FpuMul, pNumA, Offset Two, Ebx, SRC1_REAL Or SRC2_REAL
Or Eax, Eax
Jz _rRealRoots
; solutionX1
Invoke FpuDiv, Ecx, Ebx, Offset _xRoot1, SRC1_REAL Or SRC1_REAL
Or Eax, Eax
Jz _rRealRoots
; solutionX2
Invoke FpuDiv, Edx, Ebx, Edx, SRC1_REAL Or SRC2_REAL
Or Eax, Eax
Jz _rRealRoots
Invoke FpuMul, Edx, Offset NegativeOne, Offset _xRoot2, 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 : ")
; Invoke printQuadraticFormat
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)
Jmp _ExitProc
@@:
print chr$(13, 10)
print chr$("There are no real solutions for the quadratic equation ")
print chr$("but it has complex roots! ")
; The following statement call output format procedure of the quadratic
; equation
; Invoke printQuadraticFormat
print chr$(" !", 13, 10, 13, 10) ; ! will be outputted along with two
; carriage return line feeds to the screen
_ExitProc:
Ret
calculateQuadraticRoots EndP
End start
hi RuiLoureiro,
Here is my updated code. I changed your code a little bit.
The results are all zeros.
What is wrong?
---------------------------------------------------------
.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
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
.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
Two Real10 2.0 ; number to use to get the denominator in the quadratic formula
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
Four Real10 4.0 ; number to use to get a square root number 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
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
Invoke calculateQuadraticRoots
; print chr$(13, 10)
; print chr$("Error, Division by Zero!", 13, 10, 13, 10)
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
.If isequal (NumberA, NegativeOne)
; if NumberA equals to -1.0
print chr$("-1.0 X^2 ")
.ElseIf isequal (NumberA, One)
; if NumberA equals to 1.0
print chr$("1.0 X^2 ")
.ElseIf (isgreater (NumberA, One) || isless (NumberA, NegativeOne))
; if NumberA greater than 1.0 Or A_Number less than - 1.0
Invoke FpuFLtoA, 0, 5, Addr NumberA, SRC1_FPU Or SRC2_DIMM
print chr$(" X^2 ")
.EndIf
.If isless (NumberB, NegativeOne)
; if NumberB less than -1.0
Invoke FpuFLtoA, 0, 5, Addr NumberB, SRC1_FPU Or SRC2_DIMM
print chr$(" X ")
.ElseIf isequal (NumberB, NegativeOne)
; if NumberB equals to -1.0
print chr$("-1.0 X ")
.ElseIf isequal (NumberB, One)
; if NumberB equals to 1.0
print chr$("+ 1.0 X ")
.ElseIf isgreater (NumberB, One)
; if NumberB greater than 1.0
print chr$("+ ")
Invoke FpuFLtoA, 0, 5, Addr NumberB, SRC1_FPU Or SRC2_DIMM
print chr$(" X ")
.EndIf
.If isless (NumberC, NegativeOne)
; if NumberC less than -1.0
Invoke FpuFLtoA, 0, 5, Addr NumberC, SRC1_FPU Or SRC2_DIMM
.ElseIf isequal (NumberC, NegativeOne)
; if NumberC equals to -1.0
print chr$("-1.0 ")
.ElseIf isgreater (NumberC, Zero)
; if NumberC greater than 0.0
print chr$("+ ")
Invoke FpuFLtoA, 0, 5, Addr NumberC, SRC1_FPU Or SRC2_DIMM
.EndIf
Ret
printQuadraticFormat EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<< calculateXRoots procedure will calculate the two real roots in the quadratic <<
;<< formula <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateXRoots 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 solutionX1:Real10
Local solutionX2:Real10
Lea Ebx, NumB2
Invoke FpuMul, pNumB, pNumB, Ebx, SRC1_REAL Or SRC2_REAL
Or Eax, Eax
Jz _rRealRoots
Lea Ecx, Num4AC
Invoke FpuMul, pNumA, pNumC, Ecx, SRC1_REAL Or SRC2_REAL
Or Eax, Eax
Jz _rRealRoots
;
Invoke FpuMul, Ecx, Offset Four, 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
; if NumB2_4AC >= 0
;---------------------
Invoke FpuComp, Edx, Offset Zero, 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, solutionX1
Invoke FpuSub, Ebx, pNumB, Ecx, SRC1_REAL Or SRC2_REAL
Or Eax, Eax
Jz _rRealRoots
Lea Edx, solutionX2
Invoke FpuAdd, Ebx, pNumB, Edx, SRC1_REAL Or SRC2_REAL
Or Eax, Eax
Jz _rRealRoots
Lea Ebx, Num2A
Invoke FpuMul, pNumA, Offset Two, Ebx, SRC1_REAL Or SRC2_REAL
Or Eax, Eax
Jz _rRealRoots
; solutionX1
Invoke FpuDiv, Ecx, Ebx, Offset _xRoot1, SRC1_REAL Or SRC1_REAL
Or Eax, Eax
Jz _rRealRoots
; solutionX2
Invoke FpuDiv, Edx, Ebx, Edx, SRC1_REAL Or SRC2_REAL
Or Eax, Eax
Jz _rRealRoots
Invoke FpuMul, Edx, Offset NegativeOne, Offset _xRoot2, 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
Cmp Eax, 2
Je @F
print chr$(13, 10)
print chr$(" Solutions for quadratic equation : ")
; Invoke printQuadraticFormat
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)
Jmp _ExitProc
@@:
print chr$(13, 10)
print chr$("There are no real solutions for the quadratic equation ", 13, 10)
print chr$("but it has complex roots! ")
; The following statement call output format procedure of the quadratic
; equation
; Invoke printQuadraticFormat
;print chr$(" !", 13, 10, 13, 10) ; ! will be outputted along with two
; carriage return line feeds to the screen
_ExitProc:
print chr$(13, 10, 13, 10)
Ret
calculateQuadraticRoots EndP
End start
Hi etow,
See now. It is hard to convert procedures ! Dont use *** NegativeFour *** unless you change
FpuSub by FpuAdd. But not only !
; File: Eq6.asm
;................................................
.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 Macro.inc ; i used this
Include ComparisonMacros.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
.Data
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 ?
; ##############################################################################################
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
Two Real10 2.0 ; number to use to get the denominator in the quadratic formula
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
;NegativeFour Real10 - 4.0 ; number to use to get a square root number 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
; ----------------------------------------------------------------------------------------------
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
;Invoke calculateQuadraticRoots ; it is correct
call calculateQuadraticRoots ; but when we have no parameters its the same
print chr$(13, 10)
; print chr$(13, 10)
; print chr$("Error, Division by Zero!", 13, 10, 13, 10)
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
.If isequal (NumberA, NegativeOne)
; if NumberA equals to -1.0
print chr$("-1.0 X^2 ")
.ElseIf isequal (NumberA, One)
; if NumberA equals to 1.0
print chr$("1.0 X^2 ")
.ElseIf (isgreater (NumberA, One) || isless (NumberA, NegativeOne))
; if NumberA greater than 1.0 Or A_Number less than - 1.0
Invoke FpuFLtoA, 0, 5, Addr NumberA, SRC1_FPU Or SRC2_DIMM
print chr$(" X^2 ")
.EndIf
.If isless (NumberB, NegativeOne)
; if NumberB less than -1.0
Invoke FpuFLtoA, 0, 5, Addr NumberB, SRC1_FPU Or SRC2_DIMM
print chr$(" X ")
.ElseIf isequal (NumberB, NegativeOne)
; if NumberB equals to -1.0
print chr$("-1.0 X ")
.ElseIf isequal (NumberB, One)
; if NumberB equals to 1.0
print chr$("+ 1.0 X ")
.ElseIf isgreater (NumberB, One)
; if NumberB greater than 1.0
print chr$("+ ")
Invoke FpuFLtoA, 0, 5, Addr NumberB, SRC1_FPU Or SRC2_DIMM
print chr$(" X ")
.EndIf
.If isless (NumberC, NegativeOne)
; if NumberC less than -1.0
Invoke FpuFLtoA, 0, 5, Addr NumberC, SRC1_FPU Or SRC2_DIMM
.ElseIf isequal (NumberC, NegativeOne)
; if NumberC equals to -1.0
print chr$("-1.0 ")
.ElseIf isgreater (NumberC, Zero)
; if NumberC greater than 0.0
print chr$("+ ")
Invoke FpuFLtoA, 0, 5, Addr NumberC, SRC1_FPU Or SRC2_DIMM
.EndIf
Ret
printQuadraticFormat EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<< calculateXRoots procedure will calculate the two real roots in the quadratic <<
;<< formula <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateXRoots 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
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 : ")
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)
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)
Jmp _ExitProc
@@:
print chr$(13, 10)
print chr$("There are no real solutions for the quadratic equation ")
print chr$("but it has complex roots! ")
; The following statement call output format procedure of the quadratic
; equation
Invoke printQuadraticFormat
print chr$(" !", 13, 10, 13, 10) ; ! will be outputted along with two
; carriage return line feeds to the screen
_ExitProc:
;inkey ; ########### WAS USED TO TEST
Ret
calculateQuadraticRoots EndP
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
End start
Rui
etow,
If you want to replace names, make a copy of your program (save ti like eq2.asm, eq3.asm, etc.)
use the editor replace text and then test the new. If it is correct, go on. If not go back. Save it next number and repeat. Its a safe way. Sometimes there are problems with replace function: it replaces what we dont want !
Sarel,
Yes, etow has a problem with -4.
Rui
Hi 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
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include ComparisonMacros.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
.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: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
; ----------------------------------------------------------------------------------------------
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 linear
Call calculateQuadraticRoots ; no parameters its the same
; invoke calculateQuadraticRoots
print chr$(13, 10)
Jmp ToContinue
linear:
Invoke FpuComp, Addr NumberB, Offset Number0, SRC1_REAL Or SRC2_REAL
Or Eax, Eax
Jz ZeroErrors
Invoke calculateLinearRoot, Addr NumberB, Addr NumberC
print chr$(13, 10)
print chr$(" Solution to linear equation : ")
print chr$(" ")
print real10$ (NumberB)
print chr$(" X ")
print real10$ (NumberC)
print chr$(" = 0 ", 13, 10, 13, 10)
print chr$("X = ")
print real10$ (_LinearRootX)
Jmp ToContinue
ZeroErrors:
print chr$(13, 10)
print chr$(" Error, Numbers for A and B are zero! ", 13, 10)
ToContinue:
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
print chr$(" ")
print real10$ (NumberA)
print chr$(" X^2 + ")
print real10$ (NumberB)
print chr$(" X + ")
print real10$ (NumberC)
print chr$(" = 0 ", 13, 10)
Ret
printQuadraticFormat EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<< calculateLinearRoot procedure will calculate the root of the linear equation <<
;<< when NumberA is equal to 0 and NumberB is not equal to 0 and NumberC is not <<
;<< equal to 0 <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateLinearRoot Proc pNumB:DWord, pNumC:DWord
; Bx + C = 0 or Bx - C = 0
Local negativeNumC:Real10
Lea Edx, negativeNumC
Invoke FpuChs, pNumC, Edx, SRC1_REAL Or SRC2_REAL
Invoke FpuDiv, Edx, pNumB, Offset _LinearRootX, SRC1_REAL Or SRC2_REAL
_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)
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)
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)
Jmp _ExitProc
@@:
print chr$(13, 10)
print chr$("There are no real solutions for the quadratic equation : ", 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) ; ! will be outputted along with two
; carriage return line feeds to the screen
_ExitProc:
Ret
calculateQuadraticRoots EndP
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
End start
------------------------------------------------------------------------
I tried getting the solution to Linear equation to work but I could not in the above code.
I need help. Also, is there a way to get rid of the excess zeros after the decimal point in the answer to the real root solutions of the quadratic equation using the quadratic formula.
What does "lea" mean? What does "or eax, eax" do? What does "jz" mean? What does "mov eax, 2 and clc " do together? What does "mov eax, 1 and clc" instructions do together? What does "stc" do? What does "je @F" do?
I am trying to learn your code so that I know how to use it.
Please reply back soon.
Thanks
Hi RuiLoureiro,
I also have some more questions.
What does " jz _rRealRoots" mean? I know that it is a jump to _rRealRoots
What does "Jc _ExitProc " mean?
What does "Cmp Eax, 2" do?
Hi etow,
1. About «lea»
Whenever we define a LOCAL variable (inside a procedure)
like *** Local NumB2:Real10 ***, to get the initial address of that variable
in a register,for instance, EBX, we use «lea ebx, NumB2». Now, the address
of NumB2 is in EBX. It means also that, now, EBX is the pointer of NumB2. Yes ?
With global variables (defined in .DATA section ) like *** _RootX0 ***, we get
a pointer in this way: «mov ebx, offset _RootX0» ( pointer means address ).
2. «What does "or eax, eax" do? What does "jz" mean?»
Whenever we return from functions FpuDiv, FpuAdd, FpuSub, etc. etc. the value
in EAX can be 0 or 1. If it is 0 it means an error occurred. One way to see
if EAX=0 is «or eax, eax» - it activates the zero flag -and then Jump if Zero
«jz». You can do this with cmp eax, 0, then jz .... It is the same.
3. There are 3 ways of exit from *** calculateXRoots Proc ***:
a) with error the exit is EAX=0 and carry flag set (stc);
b) roots are real: EAX=1 and carry flag is cleared (clc);
c) roots are complex: EAX=2 and carry flag is cleared (clc).
Then, after you call calculateXRoots, if it comes with carry set
you can use «jc - jump on carry» to an address process the error case.
If not, you can test EAX=1 or EAX=2. But you can comment «clc» and «stc»
inside calculateXRoots and after calculateXRoots, you test EAX=0, EAX=1
EAX=2 (cmp eax, 0; cmp, eax, 1; cmp eax, 2).
4. What does "stc" do?
In the register of flags there is a flag called CARRY. It can be 0 or 1
0 means cleared and 1 means set. We have 2 instructions to clear and to set
that flag: clc and stc. You can use it whenever you want.
To jump if carry is set, use «jc»; to jump if carry is cleared, use «jnc»;
5.
or eax, eax ; activate the ZERO FLAG, doesnt change eax
jz _rRealRoots
The same as
cmp eax, 0 ; compare eax with 0
je _rRealRoots
Did you solve the Linear equation ?
;..............................................
EDIT:
; replace this
Invoke InputR10, Addr NumberC
Invoke FpuComp, Addr NumberA, Offset Number0, SRC1_REAL Or SRC2_REAL
Or Eax, Eax
Jz linear
; by this
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
;
; CONTINUE
...
;.........................................
ErrorInComp:
print chr$(13, 10)
print chr$(" Error comparing Number A against zero! ", 13, 10)
jmp ToContinue
ZeroErrors:
print chr$(13, 10)
print chr$(" Error, Numbers for A and B are zero! ", 13, 10)
and
;..........................................
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
; etc, etc....
;.........................................................................................
Inside calculateQuadraticRoots Proc:
print chr$(13, 10)
Ret ; exit here
;Jmp _ExitProc
print chr$(13, 10, 13, 10) ; ! will be outputted along with 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
RuiLoureiro
sse (sse2) - sqrtss, sqrtsd, but before chesk sign bit or just make positive by masking this bit.
hi RuiLoureiro,
I have the updated code but the program does nothing. I am sure the linear equation will not work. I need help. Please check my code below.
Thanks.
;................................................
.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
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
.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: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
; ----------------------------------------------------------------------------------------------
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 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
Jmp quadratic
;.........................................
ErrorInComp:
print chr$(13, 10)
print chr$(" Error comparing Number A against zero! ", 13, 10)
Jmp ToContinue
ZeroErrors:
print chr$(13, 10)
print chr$(" Error, Numbers for A and B are zero! ", 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
print chr$(" Solution to linear equation : ")
print chr$(" ----------------------------- ", 13, 10)
print chr$(" ")
print real10$ (NumberB)
print chr$(" X ")
print real10$ (NumberC)
print chr$(" = 0 ", 13, 10, 13, 10)
print chr$("X = ")
print real10$ (_LinearRootX)
Jmp ToContinue
;.........................................................................................
quadratic:
Call calculateQuadraticRoots
print chr$(13, 10)
print chr$(13, 10, 13, 10) ; output two carriage return line feeds to
; the screen
;......................................................
ToContinue:
Mov WantContinue, sval(input("Enter -1 to quit program : "))
print chr$(13, 10)
.EndW
_ExitProc:
print chr$(13, 10)
print chr$(" An Error occured while calculating the roots", 13, 10)
Ret
Main EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<< printQuadraticFormat will output the quadratic equation entered by <<
;<< user to the screen <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
printQuadraticFormat Proc
print chr$(" ")
print real10$ (NumberA)
print chr$(" X^2 + ")
print real10$ (NumberB)
print chr$(" X + ")
print real10$ (NumberC)
print chr$(" = 0 ", 13, 10)
Ret
printQuadraticFormat EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<< calculateLinearRoot procedure will calculate the root of the linear equation <<
;<< when NumberA is equal to 0 and NumberB is not equal to 0 and NumberC is not <<
;<< equal to 0 <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateLinearRoot Proc pNumB:DWord, pNumC:DWord
; Bx + C = 0 or Bx - C = 0
Local negativeNumC:Real10
Lea Edx, negativeNumC
Invoke FpuChs, pNumC, Edx, SRC1_REAL Or SRC2_REAL
Invoke FpuDiv, Edx, pNumB, Offset _LinearRootX, SRC1_REAL Or SRC2_REAL
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 NumberA
; pNumB is a pointer to NumberB
; pNumC is a pointer to NumberC
; Ax^2 + Bx + C = 0
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)
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)
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) ; ! will be outputted along with two
; carriage return line feeds to the screen
_ExitProc:
Ret
calculateQuadraticRoots EndP
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
End start
See the file etow11.zip below. Download it .
BUT:
Include ComparisonMacros.inc
;include Macro.inc <----------- REMOVE THIS
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateLinearRoot Proto :DWord,:DWord
InputR10 Proto :DWORD ;Ptr Real10
;**************************************************
I am sure the linear equation will work. But it is:
;<< 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
RuiLoureiro
[attachment deleted by admin]
hi RuiLoureiro,
I got it to work except to print the format of the quadratic equation I am having trouble with.
Look at PrintQuadraticFormat procedure.
I wanted to not print the 0.000000 X if NumberB is 0.0 . I am not sure how to do this.
;................................................
.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
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
.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
Number4 Real10 4.0 ; number to get part of the square root number
Minus1 Real10 - 1.0 ; use 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
; ##############################################################################################
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.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
; ----------------------------------------------------------------------------------------------
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
Jmp quadratic
;.........................................
ErrorInComp:
print chr$(13, 10)
print chr$(" Error comparing Number A against zero! ", 13, 10, 13, 10)
Jmp ToContinue
ZeroErrors:
print chr$(13, 10)
print chr$(" Error, Numbers for A and B are 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
print chr$(13, 10, 13, 10)
print chr$(" Linear Equation: Bx + C ", 13, 10, 13, 10)
print chr$(" Solution for linear equation : ", 13, 10)
print chr$(" ----------------------------- ", 13, 10)
print chr$(" ")
print real10$ (NumberB)
print chr$(" X + ")
print real10$ (NumberC)
print chr$(" = 0 ", 13, 10, 13, 10)
print chr$(" X = ")
print real10$ (_LinearRootX)
print chr$(13, 10, 13, 10, 13, 10)
Jmp ToContinue
;.........................................................................................
quadratic:
Call calculateQuadraticRoots
print chr$(13, 10) ; output two carriage return line feeds to
; the screen
;......................................................
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 real10$ (NumberA)
print chr$(" X^2 + ")
Invoke FpuComp, Addr NumberA, Offset Number0, SRC1_REAL Or SRC2_REAL
Or Eax, Eax
Jz @F
Jmp XCoefficient
@@:
print real10$ (NumberC)
print chr$(" = 0 ", 13, 10)
Jmp _printExit
XCoefficient:
print real10$ (NumberB)
print chr$(" X + ")
print real10$ (NumberC)
print chr$(" = 0 ", 13, 10)
_printExit:
Ret
printQuadraticFormat EndP
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;<< calculateLinearRoot procedure will calculate the root of the linear equation <<
;<< when NumberA is equal to 0 and NumberB is not equal to 0 and NumberC is not <<
;<< equal to 0 <<
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
calculateLinearRoot Proc pNumB:DWord, pNumC:DWord
; Bx + C = 0 or Bx - C = 0
Local negativeNumC:Real10
Lea Edx, negativeNumC
Invoke FpuChs, pNumC, Edx, SRC1_REAL Or SRC2_REAL
Invoke FpuDiv, Edx, pNumB, Offset _LinearRootX, SRC1_REAL Or SRC2_REAL
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 NumberA
; pNumB is a pointer to NumberB
; pNumC is a pointer to NumberC
; Ax^2 + Bx + C = 0
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)
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 will be outputted
; to the screen
_ExitProc:
Ret
calculateQuadraticRoots EndP
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
End start
etow,
The real10$ macro uses that format by default ("%lf"). Copy the real10$ macro into your program and modify the format string. Look up sprintf for details on the format string.
Or use this macro instead and specify the decimals parameter. ext$(val, 0, 3)
The digits and decimals parameters are optional.
ext$ MACRO r10value:REQ, digits:=<0>, decimals:=<6>
LOCAL buffer, fmt
.DATA?
fmt DWORD ?
buffer BYTE 40 DUP(?)
.CODE
IFE issize(r10value, 10)
ECHO -------------------------
ECHO ext$ - requires REAL10
ECHO -------------------------
.ERR
ENDIF
xor eax, eax
mov al, decimals
mov ah, digits
mov fmt, eax
INVOKE FpuFLtoA, ADDR r10value, fmt, ADDR buffer, (SRC1_REAL OR STR_REG)
EXITM <OFFSET buffer>
ENDM
Hi etow,
But Your code is not what i gave you in etow11.zip.
The problem is this, AFAIK: print real10$ (NumberC), prints with 6 decimal places.
To solve your problem, test NumberB. If it is 0.0, print one variable with 0 or one string with 0
edit: See what Greg said
Greg,
He has the same problem if he uses *** print ext$(NumberB, 0, 3) *** if NumberB = 0.0.
He wants to print 0.0 IF NumberB=0.0. So, he should test NumberB.
RuiLoureiro
RuiLoureiro,
OK, I thought he wanted to control the format of the printed number.
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?
etow,
Try it out for yourself.
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]
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
; ##############################################################################################
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
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
; ##############################################################################################
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]
Hi RuiLoureiro,
I don't see the printEquation file in the zip file
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
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
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
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
; ##############################################################################################
Hi
Here is the program in zip file for quadratic formula to solve quadratic equation for real solutions:
[attachment deleted by admin]