C代码转RISC-V汇编时数组地址计算相关逻辑疑问
疑问1解答
sd x31, 0(x30)的语义你理解的没错,就是将x31中的值写入x30所指向内存地址的偏移0位置。
它和D[4*j]的对应关系不是靠这一行单独实现的,是结合x30的动态更新逻辑共同实现的:
- 每次进入外层循环时,x30都会被初始化为数组D的基地址
&D[0],对应j=0时D[4*0] = D[0]的地址 - 内层循环每执行一轮,x30都会同步更新为下一轮要访问的
D[4*(j+1)]的地址
所以当前循环轮次里,x30存储的刚好就是当前D[4*j]的内存地址,直接写偏移0就可以完成赋值操作。
疑问2解答
addi x30, x30, 32确实是给x30的地址值加32字节,这里和4*j的关联逻辑要结合数组元素长度来理解:
参考解答默认数组D的元素是8字节长度的双字(对应RISC-V中sd指令的操作对象长度),C代码里的D[4*j]是元素下标,对应的字节偏移需要乘上元素长度:
字节偏移 = 元素下标 * 元素长度 = 4j * 8 = 32j
所以j每自增1,下一个目标地址&D[4*(j+1)]的字节偏移就是32*(j+1),比当前地址多32字节。x30的更新和j的自增是完全同步的:j=0时x30对应&D[0],j=1时x30加32对应&D[4],j=2时再加32对应&D[8],刚好和D[4*j]的地址一一对应,相当于用x30的增量替代了每次循环都计算基地址 + 32*j的操作,优化了执行效率。
内容的提问来源于stack exchange,提问作者Carl
相关产品推荐
相关产品推荐

