2013-10-01 3 views
0

Моя программа должна принимать два целых числа и оператор (деление, умножение, сложение, вычитание). Оттуда он при необходимости вычисляет ответ и остаток.Почему моя программа вырезана из цикла раньше?

После этого предполагается, что пользователь должен запросить другой расчет, используя (y/n) параметры. Если «да», он повторяет петли, а если нет, программа завершает работу. По какой-то причине это не позволяет мне включить опцию (y/n) и просто пропускает мой ввод и переходит прямо к завершению. Вот мой код. (Извините, новичок)

Я также получаю «Неизвестный код ошибки 45» (всплывающее окно?) Прямо перед тем, как войти в оператор.

enter image description here

# 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

Проблема здесь системный вызов 12, или, вернее, дефектные предположения, заставляющие его использовать.

Рассмотрим на мгновение значение syscall 12 (read char), которое вернется из stdin 1 символа. Проблема заключается в следующем:

Системные запросы: What operation would you like to perform?, пользователь вводит: +\n. Поскольку stdin буферизируется по строке, пользователь должен нажать клавишу ввода, что означает, что по меньшей мере два символа помещаются в буфер, когда они предназначены только для него. Это означает, что когда ваша программа переходит к следующему запросу: Do you want to go again?, в буфере все еще есть один символ: \n, и это то, что возвращается вторым syscall 12.

Теперь, когда вы понимаете проблему, я предполагаю вы можете это исправить. Лучший способ, вероятно, состоит в том, чтобы преобразовать системный столбец прочитанного символа в системный вызов read string и проверить введенную строку.

Как правило, не используйте syscall 12 для ввода пользователем с клавиатуры.

+0

спасибо. Это имеет смысл сейчас! – pearbear

Смежные вопросы