带有 jr $ra 的 mips 嵌套过程

mips nested procedure with jr $ra

我正在尝试将 FUNC 和 return 的值调回 xintersect。我认为使用 jr $ra 应该 return 给调用者,但它跳转到代码的末尾。我无法修改 FUNC,因为它是一个给定的示例测试用例。任何的想法?下面是我的 MIPS 代码:

 .globl FUNC
FUNC:  
    mul   $t0, $a0, $a0
    addi  $v0, $t0, -16
    jr    $ra
# expect 4 in $v1
main:  
    la $a0, FUNC
    li $a1, 0#a
    li $a2, 100#b
    b  xintersect
xintersect:
    subu $s0, $a2, $a1
    sltiu $t3, $s0, 1
    add $s5, [=10=], $a0
    bne $t3, 1, whileLoop
    #return the value in $v1
    add $v1, $a1, [=10=]
    jr $ra
whileLoop:
    addu $s2, $a1, $a2
    srl $a0, $s2, 1#m in $a0
    jr $s5
    slt $s2, [=10=], $v0
    beq [=10=], $s2, ifLoop
    addu $a2, [=10=], $a0
    b whileLoop
ifLoop:
    addu $a1, [=10=], $a0
    b whileLoop

下面应该是C代码:

int xintersect(int (*f) (int), int a, int b) {
 /* f(a) ≤ 0 ≤ f(b), a ≤ b */
 while (b-a > 1) {
     int m = (a+b)/2;
     if (f(m) <= 0) a = m; else b = m;
     }
 return a;
}

jr $ra 依赖于已放置在 $ra 中的 return 地址,但您使用未设置的 jr $s5 调用 FUNC $ra。请改用 jalr $s5

main中的b xintersect应该是jal xintersect,否则xintersect中的jr $ra将无法工作。还要记住 xintersect 必须将 $ra 保存在某个地方(例如在堆栈上),如果它需要同时调用 FUNC 然后能够 return 回到 main.

在我看来你在 xintersect 中也有一个无限循环。一旦你输入 whileLoop,就没有任何东西会退出循环。

你的 while 循环没有 EXIT.

要参与 jr 你需要 jal 所以我也写了 您的 $ra 未保存在 XINTERSECT 中的堆栈中:

addi $sp, $sp, -4
sw $ra, 0($sp)

和恢复

lw $ra,$sp
addi $sp,$sp,4 #restore the pointer too

globl FUNC
FUNC:  
    mul   $t0, $a0, $a0
    addi  $v0, $t0, -16
    jr    $ra
    #expect 4 in $v1

main:  
    la $a0, FUNC
    li $a1, 0#a
    li $a2, 100#b
    jal xintersect

xintersect:
    subu $s0, $a2, $a1
    sltiu $t3, $s0, 1
    add $s5, [=12=], $a0
    bne $t3, 1, whileLoop
    #return the value in $v1
    add $v1, $a1, [=12=]
    jr $ra
whileLoop:
    addu $s2, $a1, $a2
    srl $a0, $s2, 1#m in $a0
    jalr $s5
    slt $s2, [=12=], $v0
    beq [=12=], $s2, ifLoop
    addu $a2, [=12=], $a0
    b whileLoop
ifLoop:
    addu $a1, [=12=], $a0
    b whileLoop