You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

RARS编译器下RISC-V内存对齐错误修复求助(禁用伪指令)

解决RISC-V汇编地址不对齐错误并实现数组求和

首先,咱们先拆解你遇到的Load address not aligned to word boundary错误根源:你原来的代码里,lw t0,0(s0)是把数组的第一个元素值加载到了t0,而不是数组的基地址!后面用这个元素值加上偏移量计算出来的地址完全是乱的(比如第一个元素是1,加0之后地址是0x1),根本不符合RISC-V中lw指令要求的4字节对齐规则,所以才会报错。

下面是严格遵守禁用lalij等伪指令要求的修正代码,用lui获取数据段基地址,实现数组遍历求和:

.data
array:      .word 1,2,3,4,5,6,7,8,9,10,11,12,-1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11,-12,-5, 0
positiveSum:.word 0
negativeSum:.word 0

.text
main:
    # 加载.data段基地址(RARS中.data默认从0x10010000开始)
    lui s0, 0x10010       # s0 = 0x10010000,对应.data段起始地址
    
    # 初始化变量:索引t1=0,正数和s1=0,负数和s2=0
    addi t1, zero, 0      # t1作为数组索引,初始化为0
    addi s1, zero, 0      # s1存储正数累加和,初始为0
    addi s2, zero, 0      # s2存储负数累加和,初始为0

loop:
    # 计算当前数组元素的内存地址:基地址 + 索引*4(每个word占4字节)
    slli t3, t1, 2        # t3 = t1 * 4,将索引转为字节偏移
    add t3, t3, s0        # t3 = array基地址 + 字节偏移,得到当前元素地址
    
    lw t4, 0(t3)          # 加载当前数组元素到t4
    beqz t4, exit         # 遇到元素0时,退出循环
    
    # 判断元素正负,对应累加
    bltz t4, add_negative # 如果元素为负,跳转到负数累加分支
    add s1, s1, t4        # 正数则累加到s1
    jal x0, continue_loop # 跳过负数分支,继续循环

add_negative:
    add s2, s2, t4        # 负数累加到s2

continue_loop:
    addi t1, t1, 1        # 索引自增1,准备遍历下一个元素
    jal x0, loop          # 跳回循环开头(用jal x0代替伪指令j,符合要求)

exit:
    # 将计算好的正负和写回内存对应位置
    sw s1, 0x64(s0)       # positiveSum在array之后,偏移量为0x64(26个元素×4字节 - 4字节)
    sw s2, 0x68(s0)       # negativeSum偏移量为0x68
    
    # 程序终止(RARS中ebreak会触发停止运行)
    ebreak

核心修正说明:

  • 正确获取数组基地址:用lui s0, 0x10010直接拿到.data段的起始地址,数组array就从这个地址开始,不再错误加载元素值作为地址。
  • 替换伪指令:用jal x0, target代替伪指令j,这是RISC-V的真实无条件跳转指令,符合禁用伪指令的要求。
  • 地址计算逻辑修复:通过索引乘4得到字节偏移,加上基地址得到合法的对齐内存地址,解决了lw指令的对齐错误。
  • 内存偏移精准计算:根据array的元素个数,精准计算positiveSumnegativeSum的内存偏移,确保写回操作地址正确。

现在运行这段代码,就能正常遍历数组并计算正负和,不会再出现地址对齐错误了。

内容的提问来源于stack exchange,提问作者Bella

火山引擎 最新活动