【问题标题】:Recursive program in RISC-V assemblyRISC-V 汇编中的递归程序
【发布时间】:2019-03-24 18:06:22
【问题描述】:

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

【问题讨论】:

  • addi x5, x0, -2 x0?不应该是addi x5, x5, -2吗?
  • 对了,RISC-V有slli,所以不用mul
  • @Michael 感谢您指出,我复制了错误的版本,但没有解决它
  • 嗯,你在堆栈上保存和恢复x10 似乎也很奇怪。那是你的返回值,不是吗?所以你希望它发生变化。

标签: recursion assembly stack riscv


【解决方案1】:

我没有足够的声誉来添加评论,但是您是否尝试过使用调试器运行它(GDB?)而不是在纸上?这应该显示寄存器中的实际内容以及为什么它没有像您预期的那样分支。我对这些说明(学习 x86 汇编)不够熟悉,目前无法弄清楚源代码。

【讨论】:

  • 感谢您将我指向调试器,我将尝试使用那个调试器。我不知道调试器
【解决方案2】:

我现在开始工作了。我所做的更改如下:

  • 在我返回 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:

【讨论】:

    猜你喜欢
    • 2022-12-17
    • 2021-08-02
    • 2023-04-09
    • 1970-01-01
    • 2023-04-01
    • 2023-04-10
    • 1970-01-01
    • 2016-03-14
    • 1970-01-01
    相关资源
    最近更新 更多