Reputation: 1
I am trying to create a MARIE Code that waits for an INPUT from a user that is a decimal number, waits for another INPUT that are ASCII characters +,-,*,/ (being Dec 43, Dec 45, Dec 42, DEC 47) and then the last INPUT being another decimal number then solves the equation made. The code Assembles and Starts and you are able to input what is needed but for some reason Addition is Subtraction and everything else is Addition.
Below is the code I have.
ORG 100 / Start of the program at address 100
/ Step 1: Get the first number (input)
Input / Wait for the first number
Store Num1 / Store the first number in memory (Num1)
/ Step 2: Get the operator (input)
Input / Wait for the operator (+, -, *, or /)
Store Operator / Store the operator in memory (Operator)
/ Step 3: Get the second number (input)
Input / Wait for the second number
Store Num2 / Store the second number in memory (Num2)
/ Step 4: Check the operator and perform the operation
Load Operator / Load the operator into the AC (accumulator)
Subt PlusOp / Check if the operator is '+'
Skipcond 400 / If the result is 0, it means it's '+'
Jump Addition / Jump to Addition section if operator is '+'
Load Operator / Load the operator into the AC again
Subt MinusOp / Check if the operator is '-'
Skipcond 400 / If the result is 0, it means it's '-'
Jump Subtraction / Jump to Subtraction section if operator is '-'
Load Operator / Load the operator into the AC again
Subt MultiplyOp / Check if the operator is '*'
Skipcond 400 / If the result is 0, it means it's '*'
Jump Multiply / Jump to Multiply section if operator is '*'
Load Operator / Load the operator into the AC again
Subt DivideOp / Check if the operator is '/'
Skipcond 400 / If the result is 0, it means it's '/'
Jump Divide / Jump to Division section if operator is '/'
/ Invalid operator (default to 0)
Clear / Clear the accumulator (result is 0)
Store Result / Store 0 as result
Jump OutputResult / Jump to output result
Addition, Load Num1
Add Num2 / Add Num1 and Num2
Store Result / Store the result in Result
Jump OutputResult / Jump to Output Result
Subtraction, Load Num1
Subt Num2 / Subtract Num2 from Num1 (correct subtraction)
Store Result / Store the result in Result
Jump OutputResult / Jump to Output Result
Multiply, Load Num1
Store Temp / Store the first number (Num1) in Temp
Load Num2
Store Counter / Store the second number (Num2) in Counter
/ Handle negative multiplier or multiplicand
Clear / Clear the accumulator
Store Result / Initialize Result to 0
Load Counter
Skipcond 800 / Check if the multiplier (Num2) is negative
Jump PositiveMultiply
/ If multiplier is negative, negate it
Load Counter
Subt Zero
Store Counter
Jump PositiveMultiply
PositiveMultiply, Load Temp
Add Result / Add Num1 to Result (this is equivalent to repeated addition)
Store Result / Store the intermediate result
Load Counter
Subt One
Store Counter / Decrease Counter (repeat the addition)
Skipcond 400 / If Counter is 0, end the loop
Jump PositiveMultiply
/ Store result and output it
OutputResult, Load Result
Output / Output the result
Halt / End of the program
/ Division by Repeated Subtraction
Divide, Load Num1 / Load the dividend (Num1) into AC
Store Quotient / Initialize Quotient to 0
Load Num2
Store Divisor / Store the divisor (Num2)
/ Check if the divisor is 0 (division by zero)
Load Divisor
Skipcond 800 / If divisor is 0, jump to division by zero handling
Jump DivisionLoop
DivisionByZero, Clear / Clear the result
Store Result / Store 0 as the result (division by zero)
Jump OutputResult / Jump to output result
DivisionLoop, Load Num1 / Load the dividend again
Subt Divisor / Subtract the divisor from the dividend
Skipcond 800 / If result is negative, stop the loop
Store Num1 / Update the dividend with the new value
Load Quotient
Add One / Increment the quotient by 1
Store Quotient / Store the updated quotient
Jump DivisionLoop / Repeat the loop
/ Store result and output it
Load Quotient
Store Result
Jump OutputResult
/ Memory Variables
Num1, Dec 0 / Store the first number
Num2, Dec 0 / Store the second number
Result, Dec 0 / Store the result
Temp, Dec 0 / Temporary storage for multiplication
Counter, Dec 0 / Counter for multiplication loop
Operator, Dec 0 / Store the operator
Quotient, Dec 0 / Store the quotient (division result)
Divisor, Dec 0 / Store the divisor
One, Dec 1 / Constant 1 for decrementing Counter
Zero, Dec 0 / Constant 0 for negating negative numbers
PlusOp, Dec 43 / ASCII for '+'
MinusOp, Dec 45 / ASCII for '-'
MultiplyOp, Dec 42 / ASCII for '*'
DivideOp, Dec 47 / ASCII for '/'
END
Tried changing the Skipcond
but I'm not sure how to get it to process the correct Arithmetic.
100 + 50 ends up being 50.
100 - 50 ends up being 150.
100 * 10 ends up being 110.
100 / 10 ends up being 110.
Upvotes: 0
Views: 52
Reputation: 350252
You've misinterpreted the SkipCond
statement. When the tested condition is true, then the next statement is skipped, meaning it does not perform the Jump
statement you have below it, which is the opposite from what you have assumed. This mistake occurs at several places in your code.
There are several other issues, including, but not limited to:
The second input value may be zero, but your multiplication algorithm does not deal well with the case where it (Counter
) is zero. You should first test whether it is zero before adding anything.
Subt Zero
does not negate the multiplier; it achieves nothing. It should be Clear
followed by Subt Counter
.
After you negate the multiplier when it is negative, the result is output with the wrong sign. You should negate the result as compensation.
Only use comments that tell something more than just what the instruction does. A comment like this should be avoided:
Clear / Clear the accumulator
... as that is something you can find in the manual. Comments should focus on the higher goal of a set of statements.
In the division loop you have a Skipcond 800
with the intention to exit the loop, but it doesn't exit the loop (there is no Jump
).
Where you have the comment "Initialize Quotient to 0", you are not doing that. The quotient should really start with 0, as it might be that Num1
is already less than Num2
from the very start.
In the division algorithm there is no provision to deal with negative operands.
As you already have some code for flipping the sign of the second operand for the case of multiplication, and you would need something similar for both of the division operands, I would suggest to deal with sign-flipping just before identifying the operator is a multiplication or division, so that it is common for both cases. You could then store a flag to indicate whether the result sign should be flipped at the end or not.
Like many do when starting with MARIE, you include an ORG
directive. But it really does not serve a purpose here -- there is no problem if the code is loaded at the default address 0. If you were instructed to start at a different address, the reason for this should be documented in a comment.
Here is a heavily updated version of your code that addresses the above issues:
/ Initialise variables
Clear
Store FlipSign
Store Result
Input / Get input for the first operand
Store Num1
Input / Get input for the operator: either +, -, *, or /
Store Operator
Input / Get input for the second operand
Store Num2
/ Check the operator and perform the operation
Load Operator
Subt PlusOp / Check if the operator is '+'
Skipcond 400
Jump Case2 / It is not '+': check for other operators
Jump Add / It is '+': perform an addition
Case2, Load Operator
Subt MinusOp / Check if the operator is '-'
Skipcond 400
Jump Absolute / It is not '-': check the signs of operands
Jump Subtract / It is '-': perform a subtraction
/ Before checking for other operators, make the operands unsigned
Absolute, Load Num1 / Check the sign of Num1
SkipCond 000
Jump CheckSign2 / It is not negative: make the same check for Num2
Clear / It is negative: toggle the sign of Num1
Subt Num1
Store Num1
Load One / And update the flag that result must be flipped
Store FlipSign
CheckSign2, Load Num2 / Check the sign of Num2
SkipCond 000
Jump Case3 / It is not negative: continue with operator matching
Clear / It is negative: toggle the sign of Num2
Subt Num2
Store Num2
SkipCond 800 / Check if Num2 is strictly positive now
Jump OutputResult / No: Num2 is zero: we will output zero (covering also division by zero)
Load One / Num2 was made positive: toggle the flag to flip the result sign
Subt FlipSign
Store FlipSign / This will be 0 (don't flip) or 1 (flip)
/ Now that operands are unsigned, continue with operator checks
Case3, Load Operator
Subt MultiplyOp / Check if the operator is '*'
Skipcond 400
Jump Case4 / It is not '*': check for other operators
Jump Multiply / It is '*': perform a multiplication
Case4, Load Operator
Subt DivideOp / Check if the operator is '/'
Skipcond 400
Jump OutputResult / It is not '/': the operator is not valid: output 0
Jump Divide / It is '/': perform a division
Add, Load Num1
Add Num2 / Add Num1 and Num2
Store Result
Jump OutputResult
Subtract, Load Num1
Subt Num2 / Subtract Num2 from Num1
Store Result
Jump OutputResult
/ Multiplication by repeated addition
Multiply, Load Num2
Skipcond 800 / If more additions are remaining, continue the loop
Jump OutputResult / Otherwise, exit the loop
Subt One
Store Num2 / Decrease number of remaining additions
Load Result
Add Num1 / Add Num1 to Result
Store Result
Jump Multiply
/ Division by repeated subtraction
Divide, Load Num1
Subt Num2 / Subtract the divisor from the dividend
Skipcond 000
Jump DivisionNext / Num1 is not less than Num2, so continue
Jump OutputResult / Num1 is less than Num2; we have the final result
DivisionNext, Store Num1 / Update the dividend: Num1 -= Num2
Load Result
Add One / Increment the quotient by 1
Store Result
Jump Divide
/ Check whether we need to flip the sign of the result
OutputResult, Load FlipSign
SkipCond 800
Jump Output / The flag is not set: just output result
/ Flip sign
Clear
Subt Result
Store Result
Output, Load Result
Output
Halt
/ Constants
Zero, Dec 0
One, Dec 1
PlusOp, Dec 43 / ASCII for '+'
MinusOp, Dec 45 / ASCII for '-'
MultiplyOp, Dec 42 / ASCII for '*'
DivideOp, Dec 47 / ASCII for '/'
/ Variables
Num1, Dec 0 / For first input number
Num2, Dec 0 / For second input number
Operator, Dec 0 / For the operator character
Result, Dec 0 / For the result of the operation
FlipSign, Dec 0 / Flag for indicating that result sign should be flipped or not
Upvotes: 1