我是MIPS编程的新手,并且一直在努力理解MIPS程序以及它是如何流动的。任何人都可以帮助我理解它。下面是代码。
我怀疑在RTN
函数中返回$ra
,其中执行应该在jr $r
之后返回,并且sw $ra, 8($sp)
之后将存储的内容将堆叠,因为此语句首次执行时$ra
的价值是多少?它是一些垃圾价值还是我们需要承担一些价值才能理解该计划?
f: addi $sp, $sp, -12
sw $ra, 8($sp)
sw $s0, 4($sp)
sw $a0, 0($sp)
bgt $a0, $0, L1
add $v0, $0, $0
j RTN
L1: addi $t0, $0, 1
bne $t0, $a0, L2
add $v0, $0, $t0
j RTN
L2: subi $a0, $a0,1
jal f
add $s0, $v0, $0
sub $a0, $a0,1
jal f
add $v0, $v0, $s0
RTN: lw $a0, 0($sp)
lw $s0, 4($sp)
lw $ra, 8($sp)
addi $sp, $sp, 12
jr $ra
答案 0 :(得分:2)
在函数输入中,ra
保留了我们的调用方希望完成后跳转到的返回地址。
函数前导将其保存到堆栈中,因为函数主体使用jal
进行函数调用。 jal
覆盖了ra
,因此我们需要保存/恢复自己的返回地址。
f: addi $sp, $sp, -12 ; adjust stack pointer to accommodate stack frame (subtract 12 bytes)
sw $ra, 8($sp) ; save a copy of our return address
...
功能完成后,我们可以恢复保存的内容,然后使用标准jr $ra
返回,设置PC = $ ra。
...
lw $ra, 8($sp) ; restore saved return address
addi $sp, $sp, 12 ; restore stack pointer (dispose of stack frame)
jr $ra ; jump to return address
(从@PaulR的答案中复制的一些措词和代码格式似乎无法正确解释,因此我认为其所有文本都需要在代码块之外进行重写。)
答案 1 :(得分:0)
返回地址在函数前导码中保存到ra
:
f: addi $sp, $sp, -12 ; adjust stack pointer to accommodate stack frame (subtract 12 bytes)
sw $ra, 8($sp) ; save return address in ra
...
因此,当函数完成时,它可以恢复堆栈指针以处理堆栈帧,然后跳转到ra
中保存的返回地址:
...
addi $sp, $sp, 12 ; restore stack pointer (dispose of stack frame)
jr $ra ; jump to saved return address