MIPS地址错误/异常

时间:2018-08-20 05:55:18

标签: assembly mips qtspim

该代码是用于计算数字阶乘的递归块。我在PC(文本中的错误地址)中遇到了异常。我正在查看跟踪,但不知道问题出在哪里,除了我的PC正在显示垃圾值。我将代码附在下面。

.data
    prompt: .asciiz "Enter the n"
.text
    main:
        #User I/O
        li $v0, 4
        la $a0, prompt
        syscall
        li $v0, 5
        syscall
        add $a0, $v0, $zero
        jal fact
        j finish
    fact:
        addi $sp, $sp, -8  #adding two elements (reserve space), since stacks start from higher mem address
        sw $ra, 0($sp)
        sw $a0, 4($sp)

        slti $t0, $a0, 1
        beq $t0, $zero, loop

        addi $sp, $sp, 8
        addi $v0, $zero, 1

        jr $ra

    loop:
        addi $a0, $a0, -1
        jal fact    #stores address of the lw instruction and goes to label-->fact

    lw $a0, 0($sp)
    lw $ra, 4($sp)
    addi $sp, $sp, 8 #deleting 2 elements

    mul $v0, $v0, $a0
    jr $ra #until main ra, recursively go through fact(n)=fact(n-1)*n

    finish:

使用的模拟器:QtSpim

感谢您的帮助。谢谢!还要附加PC并注册值,以备不时之需。 Register values at the time of the error

1 个答案:

答案 0 :(得分:1)

与调试器一起进行单步调试,以找出在lw $ra, 4($sp)时出了什么问题,以及您实际上 jr $ra加载并跳转到了什么地方。该指令会跳转到$ra中的任何地址,并且是将PC设置为伪造的最有可能的候选者。

似乎您将$ra保存到0($sp),但是从4($sp)恢复了它,因此您正在交换arg和返回地址。

此外,您的main根本没有保存其$ra,因此您将无法从main返回。您在保存jal之前先运行$ra,所以唯一的保存/恢复操作是在fact内部(其定义与main混在一起了吗?不要那样做。跳过另一个函数的定义,只需将代码从main返回或在main底部进行退出系统调用即可。)

另外,当您j finish崩溃时,它可能会崩溃,这将使程序的末尾陷入非指令中。