MIPS汇编jal调用函数后jr $ra无法正确返回主程序问题
问题根因
你的程序出现无限循环、无法正常返回主程序的核心原因是函数内部循环的分支跳转标签写错,和栈操作、$ra寄存器保存逻辑无关。
具体错误逻辑:
- 在
trovaMax函数的FOR2循环开头,你写的循环退出判断为beq $t1,$zero,ENDFOR,这里的跳转目标ENDFOR是主程序中定义的标签,位置恰好落在参数赋值、jal trovaMax调用的前一段,而你为函数内循环结束定义的标签是ENDFOR2。 - 当循环计数器
$s0增长到等于数组长度$a1时,分支判断成立,程序直接跳回主程序的ENDFOR位置,完全不会执行函数后半段的返回值赋值、栈空间恢复、jr $ra返回逻辑。 - 跳回主程序
ENDFOR段后,代码会重复执行传参、jal trovaMax调用的流程,每一次jal都会覆盖$ra寄存器的值,最终形成无限递归调用的死循环。
修复方法
只需要修改trovaMax函数中循环退出的跳转目标,把标签从主程序的ENDFOR改成函数内部的ENDFOR2即可,修正后的循环段代码如下:
FOR2: slt $t1,$s0,$a1 beq $t1,$zero,ENDFOR2 # 修正标签,跳转到本函数内的循环结束位置 sll $t2,$s0,2 add $t2,$t2,$a0 lw $t3,0($t2) slt $t1,$s1,$t3 beq $t1,$zero,ENDIF add $s1,$t3,$zero ENDIF: addi $s0,$s0,1 j FOR2 ENDFOR2:
额外注意事项
当前你的trovaMax没有嵌套调用其他子函数,所以不需要额外保存$ra寄存器也能正常返回;如果后续给该函数增加子函数调用,记得要把$ra也压入栈空间保存,避免jal指令覆盖返回地址导致返回失败。
内容的提问来源于stack exchange,提问作者Per i Giochi
相关产品推荐
相关产品推荐

