MIPS 坏地址/异常
MIPS bad address/ Exception
该代码是一个递归块,用于计算一个数的阶乘。我在 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
使用调试器单步执行,找出 lw $ra, 4($sp)
时出了什么问题,以及 实际上 使用 jr $ra
加载和跳转的内容。该指令只是跳转到 $ra
中的任何地址,并且最有可能将 PC 设置为伪造的地址。
您似乎将 $ra
保存到 0($sp)
,但从 4($sp)
恢复了它,因此您交换了 arg 和 return 地址。
此外,您的 main
根本没有在输入时保存其 $ra
,因此您将无法从 main 中 return。你在保存$ra
之前运行一个jal
,所以只有save/restore在fact
里面(它的定义和main
混在一起了?别不要那样做。不要跳过另一个函数的定义,只需将代码从 main 放入 return 或在 main 的底部进行退出系统调用。)
此外,当您 j finish
时,您可能会崩溃,这会从您的程序末尾掉落到非指令中。
该代码是一个递归块,用于计算一个数的阶乘。我在 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
使用调试器单步执行,找出 lw $ra, 4($sp)
时出了什么问题,以及 实际上 使用 jr $ra
加载和跳转的内容。该指令只是跳转到 $ra
中的任何地址,并且最有可能将 PC 设置为伪造的地址。
您似乎将 $ra
保存到 0($sp)
,但从 4($sp)
恢复了它,因此您交换了 arg 和 return 地址。
此外,您的 main
根本没有在输入时保存其 $ra
,因此您将无法从 main 中 return。你在保存$ra
之前运行一个jal
,所以只有save/restore在fact
里面(它的定义和main
混在一起了?别不要那样做。不要跳过另一个函数的定义,只需将代码从 main 放入 return 或在 main 的底部进行退出系统调用。)
此外,当您 j finish
时,您可能会崩溃,这会从您的程序末尾掉落到非指令中。