我正在尝试在RISC-V中创建一个递归程序,但我无法让它得到正确的结果。看起来它最多只能调用自己的两倍,但我尝试在纸上运行它,一切似乎都是正确的:
addi x31, x0, 4
addi x30, x0, 2
addi x2, x0, 1600 //initialize the stack to 1600, x2= stackpointer
ecall x5, x0, 5 //read the input to x5
jal x1, rec_func
ecall x0, x10, 2 //print the result
beq x0, x0, end
rec_func:
addi x2, x2, -16 //make room in stack
sd x1, 0(x2) //store pointer and result in stack
sd x10, 8(x2)
bge x5, x31, true // if i > 3, then go to true branch
addi x10, x0, 1 // if i <= 3, then return 1
addi x2, x2, 16 // reset stack point
jalr x0, 0(x1)
true:
addi x5, x5, -2 // compute i-2
jal x1, rec_func // call recursive func for i-2
ld x1, 0(x2) // load the return address
ld x10, 8(x2) // load result from last function call
addi x2, x2, 16 // reset stack point
mul x10, x10, x30 // multiply by 2
addi x10, x10, 1 // add 1
jalr x0, 0(x1) // return
end:
这是原始程序逻辑:
if i<= 3 return 1
else return 2 * rec_func(i-2) +1
我没有足够的声誉来添加评论,但您是否尝试过使用调试器(GDB ? 而不是纸上谈兵? 这应该显示寄存器中的实际内容以及为什么它没有像您期望的那样分支。 我对这些说明(学习 x86 汇编(不够熟悉,目前无法弄清楚源代码。
我现在让它工作了。我所做的更改如下:
- 在我返回 1 的部分,我没有加载返回调用的堆栈指针
- 我将 x10 的存储删除到内存中,因为@Michael指出我正在退回它并且我不需要它。
最终代码如下所示:
addi x31, x0, 4
addi x30, x0, 2
addi x2, x0, 1600 // initialize the stack to 1600, x2= stackpointer
ecall x5, x0, 5 // read the input to x5
jal x1, rec_func
ecall x0, x10, 2 // print the result
beq x0, x0, end
rec_func:
addi x2, x2, -8 // make room in stack
sd x1, 0(x2) // store pointer and result in stack
bge x5, x31, true // if i > 3, then go to true branch
ld x1, 0(x2)
addi x10, x0, 1 // if i <= 3, then return 1
addi x2, x2, 8 // reset stack point
jalr x0, 0(x1)
true:
addi x5, x5, -2 // compute i-2
jal x1, rec_func // call recursive func for i-2
ld x1, 0(x2) // load the return address
addi x2, x2, 8 // reset stack point
mul x10, x10, x30 // multiply by 2
addi x10, x10, 1 // add 1
jalr x0, 0(x1) // return
end: