该代码是用于计算数字阶乘的递归块。我在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
答案 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
崩溃时,它可能会崩溃,这将使程序的末尾陷入非指令中。