我的程序应该采用两个整数和一个运算符(除法,乘法,加法,减法)。从那里,它会在必要时计算答案和余数。
之后,它应该通过(y / n)选项提示用户是否要进行另一次计算。如果是,则重新循环,如果不是,则退出程序。出于某种原因,它不是让我为(y / n)选择,只是跳过我的输入并直接终止。这是我的代码。 (抱歉,初学者)
在我进入操作员之前,我还得到一个“未知错误代码45”(弹出窗口?)。
# SPIM Calculator
# Computer Organization
.data
prompt: .asciiz "Welcome to SPIM Calculator 1.0!\n"
first_prompt: .asciiz "Enter the first number: "
second_prompt: .asciiz "Enter the second number: "
operator: .asciiz "Enter the operation (+, -, *, /), then press enter key: "
error_message: .asciiz "\n\nArgument is invalid. Try again!\n\n"
sp: .asciiz " "
nl: .asciiz "\n"
eq: .asciiz " = "
parl: .asciiz "("
parr: .asciiz ")"
again_prompt: .asciiz "\nWould you like to do another calculation? ( y / n ) "
ended_message: .asciiz "\nCalculations complete."
.globl main
.text
main:
#initialize
li $s0, 10
# Prompt welcome
li $v0, 4 # print string value 4
la $a0, prompt # loads address from memory
syscall
loop:
# display prompt for q.1
li $v0, 4 # loads value 4 into register v0 which is op code for print string
la $a0, first_prompt # loads address from memory, stores it in argument register
syscall # reads register $v0 for op code, sees 4 and prints string located in $a0
# get input
li $v0, 5 # load op code for getting an integer from user into register $v0
syscall # reads it and puts in $t0
move $s0, $v0 # $s0 saves it
# display prompt for q.2
li $v0, 4 # loads value 4 into register v0 which is op code for print string
la $a0, second_prompt # loads address from memory, stores it in argument register
syscall # reads register $v0 for op code, sees 4 and prints string located in $a0
# get input
li $v0, 5 # load op code for getting an integer from user into register $v0
syscall # reads it and puts in $v0
move $s1, $v0 # $s1 saves it
# display prompt for q.3
li $v0, 4 # loads value 4 into register v0 which is op code for print string
la $a0, operator # loads address from memory, stores it in argument register
syscall # reads register $v0 for op code, sees 4 and prints string located in $a0
#get input
li $v0, 12 # load op code for getting an symbol from user into register $v0
syscall # reads it and puts in $t0
move $s2, $v0 # $s0 saves it
# check symbol and use if statements to go to correct part in program
beq $s2, '*', Multiplication
beq $s2, '/', Division
beq $s2, '-', Subtraction
beq $s2, '+', Addition
# in case it is none of these
li $v0, 4 # print string value 4
la $a0, error_message # loads address from memory
syscall
Multiplication:
# perform multiplication
mult $s0, $s1
mflo $s3 # moves product to $s3
syscall
jr Print
Division:
# perform division
divu $s0, $s1
mflo $s3 # moves quotient to $s3
mfhi $s4 # move remainder to $s4
syscall
jr Print
Subtraction:
# perform subtraction
sub $s3, $s0, $s1 # moves result to $s3
syscall
jr Print
Addition:
# perform addition
add $s3, $s0, $s1 # moves result to $s3
syscall
jr Print
Print:
# print new line
li $v0, 4
la $a0, nl
syscall
# print first number
li $v0, 1 # print int
move $a0, $s0
syscall
# print space
li $v0, 4
la $a0, sp
syscall
# print operator
li $v0, 11 # print operator
move $a0, $s2
syscall
# print space
li $v0, 4
la $a0, sp
syscall
# print second number
li $v0, 1 # print int
move $a0, $s1
syscall
# print equals
li $v0, 4
la $a0, eq
syscall
# jump to printing specifically for division
beq $s2, '/', Division_Print
# print result
li $v0, 1 # print int
move $a0, $s3
syscall
# print new line
li $v0, 4
la $a0, nl
syscall
jr Again_Prompt
Division_Print:
# print quotient
li $v0, 1 # print int
move $a0, $s3
syscall
# print space
li $v0, 4
la $a0, sp
syscall
# print left parenthesis
li $v0, 4
la $a0, parl
syscall
# print remainder
li $v0, 1 # print int
move $a0, $s4
syscall
# print right parenthesis
li $v0, 4
la $a0, parr
syscall
# print new line
li $v0, 4
la $a0, nl
syscall
jr Again_Prompt
Again_Prompt:
# display prompt
li $v0, 4 # loads value 4 into register v0 which is op code for print string
la $a0, again_prompt # loads address from memory, stores it in argument register
syscall # reads register $v0 for op code, sees 4 and prints string located in $a0
# get input
li $v0, 12 # load op code for getting a character from user into register $v0
syscall # reads it and puts in $t0
move $s6, $v0 # $s6 saves it
# print new line
li $v0, 4
la $a0, nl
syscall
# determine whether or not to do another calculation
beq $s6, 'y', loop
beq $s6, 'n', Terminate
Terminate:
li $v0, 4 # loads value 4 into register v0 which is op code for print string
la $a0, ended_message # loads address from memory, stores it in argument register
syscall # reads register $v0 for op code, sees 4 and prints string located in $a0
jr $ra
答案 0 :(得分:0)
这里的问题是系统调用12,或者说导致人们使用它的错误假设。
暂时考虑syscall 12(read char)的含义,它将从stdin 1字符返回。问题是:
系统提示:What operation would you like to perform?
,用户输入:+\n
。因为stdin是行缓冲的,所以用户必须按下回车键,这意味着当缓冲区只有一个字符时,至少有两个字符被放入缓冲区。这意味着当你的程序继续下一个查询:Do you want to go again?
时,缓冲区中仍然只有一个字符:\n
这是第二个系统调用12返回的字符。
现在您已了解问题,我认为您可以解决它。最好的方法是将读取字符系统调用转换为读取字符串系统调用并检查输入的字符串。
作为宽松的规则,不要使用系统调用12来从键盘输入用户。