错误#5:未对齐的字存储器参考 [英] Error #5: Unaligned word memory reference

查看:140
本文介绍了错误#5:未对齐的字存储器参考的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆