当我加载自己的文件时 QtSpim 没有响应并在加载其他文件时抛出错误

QtSpim not responding when I load my own file and throws errors when loading other files

我正在尝试加载此文件,但 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"

但是,当另一个文件(我复制粘贴以查看它是否有效)确实加载并且我尝试 运行 它时,我会收到以下错误: 异常发生在 PC=0x00000000

读取的文本地址错误:0x00000000

试图在 0x80000180 处执行非指令

是我的代码有问题还是其他什么问题?

编辑:我正在使用简单机器设置。

Spim 期望用户代码从标签 main 开始,所以如果没有它,它会在 运行 代码时出错。

所以需要将label和.global中的_start改为main。

在两个地方使用的 beq $a3、$zero goto exit 无效,因为 beq 命令需要在 $zeroo 和要转到的标签之后有一个逗号 - 而不是 'goto label'

您还有许多系统调用语句,但没有设置值 v0 值 - 您假设它仍然相同,还是忘记这样做了?同样在某些地方,当您可能打算为系统调用设置 v0 时,看起来您看到的是 v1。

例如:

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

您想像打印 atr1 一样打印 str2,因此将 a0 设置为地址 str2(which toy did),v0 需要为 4(不是 v1)

在代码中有重复的实例,以及在根本不设置 v0 的情况下执行系统调用的地方。