factorial - 如何在RISC-V中实现阶乘函数

标签 factorial riscv

    C-code  :

int factorial(int n) 
{
if (n<1) return 1;
 else return n * factorial (n-1);
}

我尝试过实现它,但没有成功。这是我的尝试:

     goto:

 factorial:
 int factorial(int n) {
 if (n<1) goto Lthen;

 Lelse:
 tmp=factorial(n-1);
 return n*tmp;
 goto Lend;

 Lthen: return 1;
 Lend;
 }



 RISC V:
.factorial
 addi sp, sp,  -16
 sw ra, (sp)
 sw s0, 4(sp) //n
 sw s1, 8(sp) //tmp
 mv s0, a0               //a--->s0
 addi t1, zero,1 
 blt s0, t1, Lthen

   .Lelse
   mv t0, s0          // copy of n to t0
   addi s0, s0, -1   // n-1
   mv a0, s0;        // n-1--->a0
   jal factorial // factorial(a0)
   mv s1, a0         // s1=factorial(a0) //tmp
   mul a0,t0,s1        //  n*tmp ----> a0 
   ret
   j LEND



Lthen: li a0,1
ret
LEND jr ra, 0 

有人可以告诉我这样可以吗,因为我不知道如何测试它。 我不确定 return 1/或任何其他值/表达式,我们可以把它放在 a0 中并说 ret..

感谢您的宝贵时间!

最佳答案

您应该使用 $s0 作为保留值,而不是 $t0

在递归调用之前从 $s0 复制后,您应该从 $a0 中减去 1。

然后乘法将在 $a0 返回值和 $s0 保留值之间进行。

$s0 可以工作但 $t0 不行(为了保留原始 $a0 输入)的原因是,您做出(正确的)努力来保存s寄存器。

但是,您不会恢复函数尾声中保存的值,也不会削减堆栈,也不会重新加载$ra...

关于factorial - 如何在RISC-V中实现阶乘函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58068547/

相关文章:

C#:使用 Lambda 的递归函数

r - 具有因子设计的 ANCOVA 中的事后检验错误

algorithm - 如何将值向上舍入到数字的最接近因子

c - 在 C 中打印出从 (0 到 n) 的阶乘列表

assembly - 零/符号扩展是空操作,那么为什么要对每种尺寸类型进行说明呢?

c - 浮点异常的陷阱是如何生成的?

chisel - Chisel 模块中的条件端口

c - 如何将此代码转换为数组或 malloc?

api - RISCV C至UART的十六进制编译

cpu-architecture - RISC-V 与其他 ISA 之间的差异