【问题标题】:RISC-V calling conventionRISC-V 调用约定
【发布时间】:2020-10-19 06:48:39
【问题描述】:

我已经阅读了这篇文章:https://riscv.org/wp-content/uploads/2015/01/riscv-calling.pdf

但仍然无法确定 RISC-V 将参数放入哪个寄存器。

fibonacci.c 的代码是这样的:

#include <stdio.h>

unsigned long long int fibonacci(int);

int main () {
    unsigned long long int ret;

    for (int i = 0; i < 94; i++) {
        ret = fibonacci(i);
        printf("%llu\n", ret);
    }

    return 0;
}

.s 代码格式是这样的:

.global fibonacci
.type fibonacci, %function

.align 2
# unsigned long long int fibonacci(int n);
fibonacci:  
    # insert code here
    # Green card here: https://www.cl.cam.ac.uk/teaching/1617/ECAD+Arch/files/docs/RISCVGreenCardv8-20151013.pdf
    
    ret

我已尝试更改a0、a1寄存器中的值,但输出仍然没有改变。

像这样:

.global fibonacci
.type fibonacci, %function

.align 2
# unsigned long long int fibonacci(int n);
fibonacci:  
    # insert code here
    add a0, a0, a0
    addi a1, zero, 1
    # Green card here: https://www.cl.cam.ac.uk/teaching/1617/ECAD+Arch/files/docs/RISCVGreenCardv8-20151013.pdf
    
    ret

输出还是 0 1 2 3 ... ... ... 90 91 92 93

【问题讨论】:

  • 您对程序集的更改应该会产生效果。关于为什么您没有看到更改,我最好的猜测是您正在链接旧版本的程序集。请包括您正在使用的编译和链接步骤。
  • LOL 我发现了这个错误,我从 docker 中提取代码,但我在我的 IDE 上编码,它不会更改 docker 中的代码

标签: riscv


【解决方案1】:

你的斐波那契函数的调用 abi 只是输入和输出的 a0(对于 32 位 a1 也用于输出)。

Compiler explorer 是研究 C -> 汇编的非常有用的工具。在调用fibonacci 之后,C 代码将a0 移动到-32(sp),然后移动到a1 以获取以下printf

【讨论】:

  • 非特权 RISC-V 规范涵盖了第 25 章中的调用约定。a0 - a7 可用于函数参数。也可以看链接了解调用约定youtube.com/watch?v=wyjtOdgt2n8&t=734s
  • 值得注意的是,RISC-V (RV) 规范没有指定将哪些参数放入哪些寄存器。具体关于 C,您必须参考 RV 上的 C 调用约定以获取详细信息;大于一个寄存器的参数、超过 8 个参数和可变参数都是没有一种明显的方法来遵循 RV 规范的情况。不幸的是,我知道 RV 上的 C 调用约定没有一个很好的文档。
猜你喜欢
  • 2020-05-05
  • 2015-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-22
  • 2023-03-22
  • 2016-03-14
  • 2021-10-05
相关资源
最近更新 更多