QtSpim не отвечает, когда я загружаю свой собственный файл, и выдает ошибки при загрузке других файлов

Я пытаюсь загрузить этот файл, но 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.


person Dio Tsolakou    schedule 04.11.2018    source источник
comment
Размещенный вами код содержит комментарии с разрывами строк, поэтому он не будет ассемблироваться.   -  person Michael    schedule 04.11.2018
comment
@Michael Если вы говорите о комментариях в описании, то они в одну строку. Из-за того, что они длинные, они показаны здесь так, но все в одну строку. Тогда снова я бы получил сообщение об ошибке, а не о том, что программа не отвечает, если бы это было так? Редактировать: каждый комментарий находится в одной строке, они просто показаны здесь.   -  person Dio Tsolakou    schedule 04.11.2018
comment
Если все они представляют собой однострочные комментарии, вам следует отредактировать свой вопрос и исправить это. В противном случае ваш код выглядит сломанным для всех остальных.   -  person Michael    schedule 04.11.2018
comment
У вас все еще есть один комментарий с разрывом строки. По какой-то причине вы также используете слово goto в нескольких инструкциях ветвления. И вам не хватает метки main.   -  person Michael    schedule 05.11.2018
comment
@ Майкл, разве я не должен использовать goto? Кроме того, почему я должен использовать основную метку? Каждый пример, который был дан в курсе (организация компьютерных систем) относительно этого кода и любого другого кода сборки mips, который нас просят сделать, не имеет основной метки.   -  person Dio Tsolakou    schedule 05.11.2018


Ответы (1)


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

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

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

У вас также есть несколько операторов системного вызова, но не устанавливайте значения v0 value - вы предполагаете, что они все те же, или забыли это сделать? Также в некоторых местах кажется, что вы видите 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.

person lostbard    schedule 05.11.2018
comment
Большое спасибо за beq и объяснение, почему мне нужен основной лейбл. Кажется, я запутался, когда читал, как работает beq. Не могли бы вы сказать мне, какие операторы системных вызовов вы имеете в виду? Я не разбираюсь в mips32, и то, что нам дает лектор и профессор лаборатории, действительно скудно и почти не объясняет код Spim и mips32. - person Dio Tsolakou; 05.11.2018
comment
Большое спасибо за все. Я исправлю свои ошибки и посмотрю, захочет ли Спим загрузить его на этот раз. Что касается добавления $a1, $v0, $zero : в соответствии с тем, чему нас учили, это просто установить число, вставленное пользователем, которое содержит $v0, в $a1. Должен ли я использовать для этого другой регистр вместо $a1, например, $s1? - person Dio Tsolakou; 05.11.2018