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
我的编译器是 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