从 C 代码到 RISC-V 汇编代码
Going from C code to RISC-V assembly code
我有这个练习
Translate the following C code to RISC-V assembly code. Assume that the values of a, b, i, and j are in registers x5, x6, x7, and x29, respectively. Also, assume that register x10 holds the base address of the array D.
for(i=0; i<a; i++){
for(j=0; j<b; j++){
D[4*j] = i + j;
}
}
我也有评论的解决方案
Loop1:
addi x7, x0, 0 // i = 0
bge x7, x5, ENDi // while i < a
addi x30, x10, 0 // x30 = &D[0]
addi x29, x0, 0 // j = 0
Loop2:
bge x29, x6, ENDj // while j < b
add x31, x7, x29 // x31 = i + j
sd x31, 0(x30) // D[4*j] = x31
addi x30, x30, 32 // x30 = &D[4*(j+1)]
addi x29, x29, 1 // j++
jal x0, LOOP2
ENDj:
addi x7, x7, 1 // i++
jal x0, LOOP1
ENDi:
不明白的地方
sd x31, 0(x30) // D[4*j] = x31
addi x30, x30, 32 // x30 = &D[4*(j+1)]
sd x31, 0(x30)
不是说我把x31的值存到数组30的第0位吗?哪里来的突然的4*j?
addi x30, x30, 32
不是说 x30 = x30+32 吗? x30 = &D[0] 不是在第一个循环中定义的吗? j怎么突然接触到x30了?
这相当于以下内容:
for(int64_t i=0; i<a; i++){
int64_t* x30 = &D[0];
for(int64_t j=0; j<b; j++){
*x30 = i + j;
x30 += 4; // increment by 4 elements
}
}
x30 在循环中用作 'current pointer'。它指向 D 数组中的相关元素。它被初始化为第一个元素,并以 4 个元素为步长递增,模拟 4*j 部分。由于您的元素是 64 位,8 个字节,要增加 4 个元素,指针的基础地址应增加 4*8=32 个字节。
维护当前指针通常比每次都重新计算它更有效,尤其是在 RISC-V 中,因为你不能有寄存器偏移量(没有 str x31, [x30, x29]
)。
我有这个练习
Translate the following C code to RISC-V assembly code. Assume that the values of a, b, i, and j are in registers x5, x6, x7, and x29, respectively. Also, assume that register x10 holds the base address of the array D.
for(i=0; i<a; i++){
for(j=0; j<b; j++){
D[4*j] = i + j;
}
}
我也有评论的解决方案
Loop1:
addi x7, x0, 0 // i = 0
bge x7, x5, ENDi // while i < a
addi x30, x10, 0 // x30 = &D[0]
addi x29, x0, 0 // j = 0
Loop2:
bge x29, x6, ENDj // while j < b
add x31, x7, x29 // x31 = i + j
sd x31, 0(x30) // D[4*j] = x31
addi x30, x30, 32 // x30 = &D[4*(j+1)]
addi x29, x29, 1 // j++
jal x0, LOOP2
ENDj:
addi x7, x7, 1 // i++
jal x0, LOOP1
ENDi:
不明白的地方
sd x31, 0(x30) // D[4*j] = x31
addi x30, x30, 32 // x30 = &D[4*(j+1)]
sd x31, 0(x30)
不是说我把x31的值存到数组30的第0位吗?哪里来的突然的4*j?
addi x30, x30, 32
不是说 x30 = x30+32 吗? x30 = &D[0] 不是在第一个循环中定义的吗? j怎么突然接触到x30了?
这相当于以下内容:
for(int64_t i=0; i<a; i++){
int64_t* x30 = &D[0];
for(int64_t j=0; j<b; j++){
*x30 = i + j;
x30 += 4; // increment by 4 elements
}
}
x30 在循环中用作 'current pointer'。它指向 D 数组中的相关元素。它被初始化为第一个元素,并以 4 个元素为步长递增,模拟 4*j 部分。由于您的元素是 64 位,8 个字节,要增加 4 个元素,指针的基础地址应增加 4*8=32 个字节。
维护当前指针通常比每次都重新计算它更有效,尤其是在 RISC-V 中,因为你不能有寄存器偏移量(没有 str x31, [x30, x29]
)。