带有 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
我正在尝试将 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