use*_*366 4 assembly mips mips64
我是 MIPS 编程的新手,一直在努力理解 MIPS 程序及其流程。我该如何理解呢?下面是代码。
我的疑问是RTN函数返回的位置$ra是执行应该在之后返回的位置jr $ra:
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
Run Code Online (Sandbox Code Playgroud)
在函数入口处,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
...
Run Code Online (Sandbox Code Playgroud)
当函数完成后我们可以恢复我们保存的东西,然后使用标准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
Run Code Online (Sandbox Code Playgroud)
(一些措辞和代码格式是从 @PaulR 的答案复制的,这似乎解释不正确,所以我觉得它的所有文本都需要在代码块之外重写。)