Mips 加载自己的文件时QtSpim没有响应,加载其他文件时抛出错误

Mips 加载自己的文件时QtSpim没有响应,加载其他文件时抛出错误,mips,qtspim,Mips,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

我正在尝试加载此文件,但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希望用户代码从label main开始,因此如果没有它,运行代码时会出错

因此,您需要在标签和.global中将_start更改为main

在两个位置使用的beq$a3、$zero goto exit无效,因为beq命令要求$zero后面有一个逗号,并且要转到的标签-而不是“goto label”

您也有许多syscall语句,但是不要设置值v0 value-您假设它仍然是相同的,或者忘记了这样做?此外,在某些地方,当您可能打算为系统调用设置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
la $a0, str2    # loads str2 address to $a0
li $v1, 4   # loads $v1 with the contents of $a0 to print it
syscall     # prints str2
将v0设置为5为读取systecall做好准备-不确定add a1、v0应该执行什么操作,但在系统调用之后,、v0将保留读取值。现在需要存储在某个地方

下一行:

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
您希望打印与打印atr1类似的str2,因此a0被设置为地址str2(玩具所做的),v0需要为4(而不是v1)


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

Spim希望用户代码从label main开始,因此如果没有它,运行代码时会出错

因此,您需要在标签和.global中将_start更改为main

在两个位置使用的beq$a3、$zero goto exit无效,因为beq命令要求$zero后面有一个逗号,并且要转到的标签-而不是“goto label”

您也有许多syscall语句,但是不要设置值v0 value-您假设它仍然是相同的,或者忘记了这样做?此外,在某些地方,当您可能打算为系统调用设置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
la $a0, str2    # loads str2 address to $a0
li $v1, 4   # loads $v1 with the contents of $a0 to print it
syscall     # prints str2
将v0设置为5为读取systecall做好准备-不确定add a1、v0应该执行什么操作,但在系统调用之后,、v0将保留读取值。现在需要存储在某个地方

下一行:

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
您希望打印与打印atr1类似的str2,因此a0被设置为地址str2(玩具所做的),v0需要为4(而不是v1)


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

您发布的代码中包含带换行符的注释,因此它不会进行汇编。@Michael如果您在描述中谈论注释,它们在一行中。由于它们很长,所以在这里是这样显示的,但都在一行中。如果是这样的话,我不是会得到一个错误,而不是程序没有响应吗?编辑:每一条评论都在一行中,它们在这里就是这样显示的。如果它们都是单行评论,那么你应该编辑你的问题并解决它。否则,您的代码在其他人看来都已损坏。您仍有一条注释中有换行符。出于某种原因,您还在几个分支指令中使用了单词
goto
。你缺少了一个
main
标签。@迈克尔,我不应该用goto吗?还有,我为什么要使用主标签?课程(计算机系统的组织)中给出的关于此代码和要求我们执行的任何其他mips汇编代码的每个示例都没有主标签。您发布的代码中包含带换行符的注释,因此无法汇编。@Michael如果您指的是说明中的注释,他们在一条线上。由于它们很长,所以在这里是这样显示的,但都在一行中。如果是这样的话,我不是会得到一个错误,而不是程序没有响应吗?编辑:每一条评论都在一行中,它们在这里就是这样显示的。如果它们都是单行评论,那么你应该编辑你的问题并解决它。否则,您的代码在其他人看来都已损坏。您仍有一条注释中有换行符。出于某种原因,您还在几个分支指令中使用了单词
goto
。你缺少了一个
main
标签。@迈克尔,我不应该用goto吗?还有,我为什么要使用主标签?课程(计算机系统的组织)中给出的关于此代码和要求我们执行的任何其他mips汇编代码的每个示例都没有主标签。非常感谢beq,并解释了我为什么需要主标签。看来我在读beq的工作原理时搞砸了。你介意告诉我你指的是哪个syscall语句吗?我不精通mips32,讲师和实验室教授给我们的信息非常稀少,几乎没有解释Spim和mips32代码。非常感谢您所做的一切。我将纠正我的错误,看看Spim这次是否愿意加载它。至于add$a1、$v0、$zero:根据我们所学的,它只是将用户插入的$v0持有的数字设置为$a1。我应该使用另一个寄存器而不是$a1,比如$s1吗?非常感谢beq,并解释了为什么我需要主标签。看来我在读beq的工作原理时搞砸了。你介意告诉我你指的是哪个syscall语句吗?我不精通mips32以及