【问题标题】:Why "long long" arguments need to "aligned even-odd register pair" in RISC-V为什么“长长”参数需要在 RISC-V 中“对齐奇偶寄存器对”
【发布时间】:2021-01-05 08:23:01
【问题描述】:

正如RISC-V calling convention documentation 所说:

当在堆栈上传递两倍于指针字大小的原始参数时,它们是 自然对齐。当它们在整数寄存器中传递时,它们驻留在对齐的奇偶 寄存器对,偶数寄存器保存最低有效位。例如,在 RV32 中, 函数 void foo(int, long long) 在 a0 中传递它的第一个参数,在 a2 中传递它的第二个参数, 一个3。 a1 中没有传递任何内容。

为什么不直接使用a1a2 而不是a2a3?所以我们可以通过寄存器传递更多的参数。

【问题讨论】:

    标签: assembly calling-convention riscv


    【解决方案1】:

    通常,这样做是为了让简单的代码可以将所有寄存器刷新到内存并获得您所期望的,就好像首先使用内存来传递良好对齐的参数一样——这通常很重要带有可变参数函数。

    但是,我们应该注意,对于非可变参数函数,clang 和 gcc 都不会直接遵循这一点。他们都使用a0 表示inta1a2 表示long long(其中a1 是低阶,a2long long 的高阶)。

    long long square(int num, long long foo) {
        return foo + 100;
    }
    

    结果

    square:
        addi    a0, a1, 100
        sltu    a1, a0, a1
        add     a1, a1, a2
        ret
    

    clang:https://godbolt.org/z/9Pez4r

    gcc:https://godbolt.org/z/b4dMsr


    只有当我们使用可变参数时,我们才会看到编译器跳过 a1:

    long long square(int num, ...);
    
    int test () {
        square ( 100, (long long) 200 );
    }
    

    结果

    test:
        addi    a0, zero, 100
        addi    a2, zero, 200
        mv      a3, zero
        tail    square
    

    https://godbolt.org/z/4xWc1E

    【讨论】:

      猜你喜欢
      • 2020-08-27
      • 2023-03-29
      • 1970-01-01
      • 1970-01-01
      • 2020-04-18
      • 1970-01-01
      • 1970-01-01
      • 2021-05-18
      • 2020-10-18
      相关资源
      最近更新 更多