MIPS 程序 jr $ra 指令和堆栈处理

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)

Pet*_*des 5

在函数入口处,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 的答案复制的,这似乎解释不正确,所以我觉得它的所有文本都需要在代码块之外重写。)