错误#5:未对齐的字存储器参考 [英] Error #5: Unaligned word memory reference
问题描述
在使用MIPS的Dijkstra算法的实现中,我试图构建一个整数数组来表示边(源索引|目标索引|权重).
I am attempting to build an array of integers to represent edges (index of source | index of destination | weight) in an implementation of Dijkstra’s Algorithm using MIPS.
在使用rsim运行时,出现未对齐字存储器参考"错误.我想我可能会误解什么是内存对齐.我的数据在下面
On running with rsim, I am getting an "unaligned word memory reference" error. I think I may be misunderstanding what memory alignment refers to. My .data is below
.data
.align 4
enterNode: .asciiz "Enter the number of nodes: "
enterEdges: .asciiz "Enter the number of edges: "
enterSource: .asciiz "Enter source: "
enterDestination: .asciiz "Enter destination: "
enterWeight: .asciiz "Enter weight: "
newLine: .asciiz "\n"
min_nodes: .word 1
max_nodes: .word 20
error1: .asciiz "Invalid number of nodes. Must be between 1 and 20.\n"
error2: .asciiz "Invalid number of edges. Must be between 0 and 400.\n"
edgeArr: .space 4800
# source | destination | weight
input: .space 5
在.text中,我正在循环边数,以将数据输入到数组中,但这似乎是我引用或计算地址的方式不正确.
In the .text, I am looping for the number of edges to input the data into the array, but it seems the way I am referring to or calculating the address is incorrect.
addi $t0, $zero, 0 # Edge counter
la $t1, edgeArr
addi $t2, $zero, 0
loop:
# Source
addi $v0, $zero, PRINT_STRING # Print user prompt
la $a0, enterSource
syscall
addi $v0, $zero, READ_INT # Take user input
syscall
add $t3, $t2, $t2 # Calculate address in array
add $t3, $t3, $t3
add $t3, $t1, $t3
sw $v0, ($t3)
addi $t2, $t2, 1
# ...destination and weight are effectively identical to source...
# Loop condition
addi $t0, $t0, 1
slt $t4, $t0, $s1
bne $t4, $zero, loop
我已经看过几个类似的问题,但是它们似乎并不能完全解决我误会的部分,而从这双新鲜的眼睛中我真的可以从中受益.
I’ve looked at several similar questions but they don’t seem to quite address the portion I’m misunderstanding, and I could really benefit from a fresh pair of eyes looking at this.
推荐答案
在.align 4
和.space
指令之间有一些字符串. ( .word
在经典MIPS汇编器中隐式对齐4类似于MARS ,但.space
却没有.)
You have some strings between the .align 4
and your .space
directive. (.word
implicitly aligns by 4 in classic MIPS assemblers like MARS, but .space
doesn't.)
.align 4
填充以使当前位置为2^4 = 16
的倍数. (您可能希望.align 2
获得1<< 2 = 4字节对齐). 字符串的总大小不是4的倍数,因此您的.space
指令不在字对齐的内存地址.
.align 4
pads to make the current position a multiple of 2^4 = 16
. (You probably want .align 2
to get 1<<2 = 4 byte alignment). The total size of the strings are not a multiple of 4, so your .space
directives are not at word-aligned memory addresses.
首先解决单词对齐的对象,然后再处理奇数长度的数据的问题.
.data
.align 4
min_nodes: .word 1
max_nodes: .word 20
edgeArr: .space 4800
# source | destination | weight
input: .space 5 # 5 bytes??
enterNode: .asciiz "Enter the number of nodes: "
enterEdges: .asciiz "Enter the number of edges: "
enterSource: .asciiz "Enter source: "
enterDestination: .asciiz "Enter destination: "
enterWeight: .asciiz "Enter weight: "
newLine: .asciiz "\n"
error1: .asciiz "Invalid number of nodes. Must be between 1 and 20.\n"
error2: .asciiz "Invalid number of edges. Must be between 0 and 400.\n"
如果min_nodes
是生成时常量,请使用.equ
定义它,而不是完全将其存储在内存中. (因此您可以将其用作立即数)
If min_nodes
is a build-time constant, define it with .equ
instead of storing it in memory at all. (So you can use it as an immediate constant)
.equ min_nodes, 1
.equ max_nodes, 20
...
li $t0, min_modes
或sltiu $t1, $t0, min_modes
如果$t0 < min_nodes
(无符号)设置$t1=1
,否则将其设置为零.顺便说一句,您可以只使用一个分支进行范围检查:
Or sltiu $t1, $t0, min_modes
to set $t1=1
if $t0 < min_nodes
(unsigned), otherwise set it to zero. And BTW, you can do a range check with only one branch:
addui $t1, $t0, -1
then compare against 19 (unsigned)
小于1的值将换成一个大的无符号值(并大于19).大于20的值仍将大于19.
Values less than 1 will wrap to a large unsigned value (and compare greater than 19). Values greater than 20 will still be greater than 19.
您也不需要将字符串常量与读写值混合使用.如果您的汇编程序支持.rodata
或.section .rodata
,则只读字符串将放入可执行文件的文本段中,因此它们具有写保护.
You also don't need to mix your string constants with read-write values. If your assembler supports a .rodata
or .section .rodata
, your read-only strings go in the text segment of your executable so they're write-protected.
IIRC,火星没有.
IIRC, MARS doesn't.
这篇关于错误#5:未对齐的字存储器参考的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!