RISC-V 加载地址未与字边界对齐

RISC-V Load address not aligned to word boundary

我的编译器是 RARS。

问题来了。 有人告诉我,我需要定义一个内存基地址,并且不允许使用伪指令。所以,我不能使用 la, li, and j

当我尝试这样做时,出现了这个错误:

Error in /Users/SumOfArray.asm line 22: Runtime exception at 0x00400018: Load address not aligned to word boundary 0x00000001

Go: execution terminated with errors

我认为有错误的第22行是这一行: lw t4,0(t3) 创建 lui 指令后。我将需要遍历它以将值保存到数组中。

我想我想问的是如何修复下面的代码,让 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:
    lui s0, 0x10010
        lw t0,0(s0)      #load array to register t0 
        lw s1,0(s0)      #load the positive sum to s1, and negative sum to s2           
        lw s2,0(s0)

loop:                   #store values in an array using loop
    slli t3,t1,2
    add t3,t3,t0        #add the base address and the above result
    lw t4,0(t3)         #load the word from above address into t4
    beqz t4,exit        #exit loop when reaching 0

unsigned int hello;
unsigned int world;
void fun ( void )
{
    hello++;
    world++;
}

-Ttext=0x1000 -Tdata=0x20000300 

Disassembly of section .text:

00001000 <fun>:
    1000:   20000637            lui x12,0x20000
    1004:   200006b7            lui x13,0x20000
    1008:   30462703            lw  x14,772(x12) # 20000304 <hello>
    100c:   3006a783            lw  x15,768(x13) # 20000300 <__DATA_BEGIN__>
    1010:   0705                    addi    x14,x14,1
    1012:   0785                    addi    x15,x15,1
    1014:   30e62223            sw  x14,772(x12)
    1018:   30f6a023            sw  x15,768(x13)
    101c:   8082                    ret

Disassembly of section .sbss:

20000300 <world>:
20000300:   0000                    unimp
    ...

20000304 <hello>:
20000304:   0000                    unimp
    ...

fun:
    lui a2,%hi(hello)
    lui a3,%hi(world)
    lw  a4,%lo(hello)(a2)
    lw  a5,%lo(world)(a3)
    addi    a4,a4,1
    addi    a5,a5,1
    sw  a4,%lo(hello)(a2)
    sw  a5,%lo(world)(a3)
    ret

您当然可以对这些偏移量进行硬编码,只要您确实这样做了。您没有显示您的链接描述文件或地址 space 对 .text 和 .data 的需求,以查看它们如何适合您的代码。如果这是某种计算有多少数字是正数和多少负数的程序,那么您需要 1) 遍历数组和 2) 找到保存计数的位置。

如果您硬编码不正确,那么代码可能 运行 不正确,因为您似乎没有提供与该特定问题相关的任何信息。您有一些碎片,但没有与问题相关的关键信息。

在编写任何更多代码之前,您应该重新开始,只循环遍历数组并查看它是否有效,然后开始处理每个元素,然后记录分数。

您遇到的问题是您试图将 lw 与地址 (t1 << 2) + t0 一起使用。 T0 在第一次使用时等于 1(除非它同时被修改),这给出了一个未对齐的字地址。不受支持(或者至少默认情况下不支持)这会导致您看到的错误。

可能是默认情况下禁用了未对齐的访问。规范说明了什么:

For best performance, the effective address for all loads and stores should be naturally aligned for each data type (i.e., on a four-byte boundary for 32-bit accesses, and a two-byte boundary for16-bit accesses). The base ISA supports misaligned accesses, but these might run extremely slowly depending on the implementation. Furthermore, naturally aligned loads and stores are guaranteed to execute atomically, whereas misaligned loads and stores might not, and hence require additional synchronization to ensure atomicity.

为避免您遇到的错误,有两种可能性:
您确实需要进行错位访问,并且必须启用此功能。
你想要的是读取第一个单词,第二个......然后你需要做的是移动你从数组中获得的元素(向左移动 2)。

lw s1,0(s0)      #load the positive sum to s1, and negative sum to s2           
lw s2,0(s0)

可能需要替换为:

lw t4,0(t3)     
sw s1, 0(s0)    
sw s2, 4(s0)    

还有:

lui s0, 0x10010
    lw t0,0(s0)   #load array to register t0 
    lw s1,0(s0)   #load the positive sum to s1, and negative sum to s2           
    lw s2,0(s0)

需要替换为:

main:
    la t0, array
    la s0, positiveSum