QtSpim не отвечает при загрузке собственного файла и выдает ошибки при загрузке других файлов - PullRequest
0 голосов
/ 04 ноября 2018

Я пытаюсь загрузить этот файл, но QtSpim перестает отвечать при этом

# Description : This program reads two user inserted integers and asks the 
# user which is their greatest common divisor. 
# If the user answers correctly the program congratulates the user, if 
# not, the user is asked to try again.

    .text
    .globl _start

_start:
    la $a0, str1    # loads str1 address to $a0
    li $v0, 4   # loads $v0 with the contents of $a0 to print it
    syscall     # prints str1

    li $v0, 5   # reads the first user inserted integer from the console and 
                # stores it to $v0
    add $a1, $v0, $zero # stores the first integer from $v0 to $a1
    syscall     # executes the previous commands


    la $a0, str2    # loads str2 address to $a0
    li $v1, 4   # loads $v1 with the contents of $a0 to print it
    syscall     # prints str2

    li $v1, 5   # reads the second user inserted integer from the console 
                # and stores it to $v1
    add $a2, $v1, $zero # stores the second integer from $v1 to $a2
    syscall     # executes the previous commands

    la $a0, str3    # loads str3 address to $a0
    li $v0, 4   # loads $v0 with the contents of $a0 to print it
    syscall     # prints str3

    jal gcd     # calls the method named gcd
    syscall

    gcd:
        # y = a % b;
        rem $a3, $a1, $a2   # stores the remainder of the division of the 
                            # first integer with the second to $a3

        # while (y != 0) {
        #   a = b;
        #   b = y;
        #   y = a % b;
        # }
        again:
            # y = 0; break;
            beq $a3, $zero goto exit    # if the contents of $a3 equal zero, 
                                        # go to exit
            syscall
            # a = b;
            add $a1, $a2, $zero # stores the contents of the 2nd integer to 
                                # the register of the 1st
            syscall
            # b = y;
            add $a2, $a3, $zero # stores the contentnts of y to the register 
                                # of the 2nd integer
            syscall
            # y = a % b;
            rem $a3, $a1, $a2   # stores the remainder of the division of 
                                # the first integer with the second to $a3
            j again         # jumps to again to do the next iteration of the 
                            # loop
            syscall
        exit:
            jal printQuestion   # calls the method named printQuestion
            syscall


    printQuestion:
        loop:
            li $v0, 5   # reads the user's answer from the console and 
                        # stores it to $v0
            add $s0, $v0, $zero # stores the user's answer from $v0 to $s0
            syscall     #executes the previous commands
            # s = b;
            beq $s0, $a2 goto end   # if the contents of $s0 are equal with 
                                    # the contents of $a2
            la $a0, str5    # loads str5 address to $a0
            li $v1, 4   # loads $v1 with the contents of $a0 to print it
            syscall     # prints str5

            la $a0, str6    # loads str6 address to $a0
            li $v1, 4   # loads $v1 with the contents of $a0 to print it
            syscall     # prints str6
            j loop      # jumps to loop
        end:
            la $a0, str4    # loads str4 address to $a0
            li $v1, 4   # loads $v0 with the contents of $a0 to print it
            syscall     # prints str4


    .data
str1: .asciiz "Please insert the first integer : \n"    
str2: .asciiz "Please insert the second integer : \n"
str3: .asciiz "Which is the GCD of the first and second integer? \n"
str4: .asciiz "Congratulations! \n"
str5: .asciiz "Wrong answer. Please try again. \n"
str6: .asciiz "Which is the GCD? \n"

Однако, когда загружается другой файл (который я скопировал, чтобы посмотреть, работает ли он), и я пытаюсь запустить его, я получаю следующие ошибки: Исключение произошло на ПК = 0x00000000

Неверный адрес в тексте: 0x00000000

Попытка выполнить не-инструкцию в 0x80000180

Это ошибка моего кода или что-то еще не так?

Редактировать: я использую настройку Simple Machine.

1 Ответ

0 голосов
/ 05 ноября 2018

Spim ожидает, что пользовательский код запускается с метки main, поэтому без него при запуске кода будет происходить ошибка.

Так что вам нужно изменить _start на main в метке и .global.

Выход goto beq $ a3, $ zero используется в двух местах недопустимо, так как команда beq ожидает запятую после $ zeroo и метку для перехода, а не 'goto label'

У вас также есть несколько операторов syscall, но вы не устанавливаете значение v0 - вы предполагаете, что оно все еще то же самое, или забыли это сделать? Также в некоторых местах кажется, что вы видите v1, когда вы, вероятно, хотели установить v0 для системного вызова.

Например:

la $a0, str1    # loads str1 address to $a0
li $v0, 4   # loads $v0 with the contents of $a0 to print it
syscall     # prints str1

Устанавливает v0 в 4, готовясь к системе печати строк, которая ожидает, что строка будет печатать в a0 (которую вы настроили)

Следующие строки:

li $v0, 5   # reads the first user inserted integer from the console and 
            # stores it to $v0
add $a1, $v0, $zero # stores the first integer from $v0 to $a1
syscall     # executes the previous commands

Установка v0 на 5 готовится к системному вызову чтения - не уверен, что должен делать add a1, v0, но после системного вызова, v0 будет хранить значение чтения. что сейчас нужно где-то хранить.

Следующие строки:

la $a0, str2    # loads str2 address to $a0
li $v1, 4   # loads $v1 with the contents of $a0 to print it
syscall     # prints str2

Вы хотите напечатать str2 аналогично тому, как вы печатали atr1, поэтому a0 устанавливается на адрес str2 (что и сделала игрушка), v0 должно быть 4 (не v1)

В коде встречаются повторные случаи, а также места, где вы выполняете системный вызов, вообще не устанавливая v0.

...