根据用户选择执行加法、减法、乘法或除法。为什么当用户选择加法时,会执行减法?

问题描述 投票:0回答:1

我正在尝试创建一个 MARIE 代码,它等待用户输入的十进制数字,等待另一个输入,即 ASCII 字符 +、-、*、/(即 Dec 43、Dec 45、Dec 42、DEC) 47) 然后最后一个输入是另一个十进制数,然后求解所得出的方程。代码组装并开始,您可以输入所需的内容,但由于某种原因,加法是减法,其他一切都是加法。

下面是我的代码。

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

尝试更改

Skipcond
,但我不确定如何让它处理正确的算术。

100 + 50 最终是 50。

100 - 50 最终成为 150。

100 * 10 最终为 110。

100 / 10 最终为 110。

assembly marie
1个回答
0
投票

您误解了

SkipCond
的声明。当测试条件为 true 时,下一个语句是 skipped,这意味着它不会执行下面的
Jump
语句,这与您的假设相反。此错误发生在代码中的多个位置。

还有其他几个问题,包括但不限于:

  • 第二个输入值可能为零,但您的乘法算法不能很好地处理它(

    Counter
    )为零的情况。在添加任何内容之前,您应该首先测试它是否为零。

  • Subt Zero
    不会否定乘数;它一无所获。应该是
    Clear
    ,然后是
    Subt Counter

  • 当乘数为负时取反后,结果会以错误的符号输出。你应该否定结果作为补偿。

  • 仅使用说明内容超出说明内容的注释。应避免这样的评论:

    Clear / Clear the accumulator
    

    ...因为这是您可以在手册中找到的内容。评论应集中于一组陈述的更高目标。

  • 在除法循环中,您有一个

    Skipcond 800
    旨在退出循环,但它不会退出循环(没有
    Jump
    )。

  • 如果您有注释“将商初始化为0”,则您没有这样做。商实际上应该从 0 开始,因为可能从一开始

    Num1
    就已经小于
    Num2

  • 除法算法中没有处理负操作数的规定。

    由于您已经有一些用于在乘法情况下翻转第二个操作数的符号的代码,并且您需要两个除法操作数类似的代码,因此我建议在识别运算符是一个之前处理符号翻转乘法或除法,因此这两种情况都是通用的。然后,您可以存储一个标志来指示结果符号是否应在末尾翻转。

  • 就像许多人在开始使用 MARIE 时所做的那样,您包含一个

    ORG
    指令。但它在这里确实没有任何作用——如果代码加载到默认地址 0 就没有问题。如果您被指示从不同的地址开始,则应在注释中记录其原因。

这是代码的大幅更新版本,可解决上述问题:

              / 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
© www.soinside.com 2019 - 2024. All rights reserved.