【发布时间】:2021-01-30 06:10:16
【问题描述】:
int a[10] = {1,2,3,4,5,6,7,8,9,10};
for (int i = 0; i < 10; i++)
{
if( a[i] > 5)
//do something
我想将上面的 C 代码翻译成 Risc-V 程序集。这是我到目前为止所拥有的,但我对数组的初始化、存储和访问有些困惑:
#create stack
addi sp, sp, -40
#save s0
sw s0, 40(sp)
#update s0
addi s0, sp, 40
li x18, 1
sw x18, -40(s0)
li x18, 2
sw x18, -36(s0)
li x18, 3
sw x18, -32(s0)
li x18, 4
sw x18, -28(s0)
li x18, 5
sw x18, -24(s0)
li x18, 6
sw x18, -20(s0)
li x18, 7
sw x18, -16(s0)
li x18, 8
sw x18, -12(s0)
li x18, 9
sw x18, -8(s0)
li x18, 10
sw x18, -4(s0)
addi x5, x0, x0 //x5 = i = 0
addi x31, x0, 10 //x31 = 10
Func:
//do something
Loop:
lw x10, 0(s0) //x10 = a[i]
bgt x10, 5, Func //if(a[i] > 5)
addi s0, s0, 4 //&a[i++]
addi x5, x5, 1 //i = i + 1
blt x5 x31, Loop //if condition (i < 10)
这种方法正确吗?
【问题讨论】:
-
int是 32 位类型,所以如果我没记错 RISC-Vsw是 32 位存储,那么您在完全展开的初始化“循环”中会留下空白.通常你不会在像这样不进行任何调用的函数中使用s0;选择t0或另一个您无需保存/恢复即可使用的呼叫破坏寄存器。并且不要将s0/t0ABI 名称与x18编号名称混用:很容易不小心将两个名称用于同一个寄存器并踩到自己的脚趾。无论如何,如果您想要一个示例,请查看编译器输出 (godbolt.org)。