作为1D阵列(MIPS)实现的2D阵列的内存寻址问题

作为1D阵列(MIPS)实现的2D阵列的内存寻址问题,mips,memory-address,Mips,Memory Address,我试着把二维拼图表示成一维数组。目前,我正在尝试测试一个简单的2x2空单元格拼图。在MIPS中,定义如下: puzzle: .word 0, 0, 0, 0 对于测试,这应该是我得到的输出: +---+---+ | | | 但是,我得到的是: +---+---+ | | | | Error #16: Attempt to use nonexistent memory Fault address: 004000d0 Register contents:

我试着把二维拼图表示成一维数组。目前,我正在尝试测试一个简单的2x2空单元格拼图。在MIPS中,定义如下:

puzzle:
    .word 0, 0, 0, 0
对于测试,这应该是我得到的输出:

+---+---+
|   |   |
但是,我得到的是:

+---+---+
|   |   |   |
Error #16:  Attempt to use nonexistent memory

Fault address:  004000d0

Register contents:

 $zero: 00000000   $at: 00000000   $v0: 00000004   $v1: 00000000
   $a0: 00000000   $a1: 00000015   $a2: 00000002   $a3: 00000000
   $t0: 00000000   $t1: 00000054   $t2: 00000000   $t3: 00000000
   $t4: 00000000   $t5: 00000000   $t6: 00000000   $t7: 00000000
   $s0: 00000002   $s1: 00000000   $s2: 00000015   $s3: 10000054
   $s4: 00000000   $s5: 00000000   $s6: 00000000   $s7: 00000000
   $t8: 00000000   $t9: 00000000   $k0: 00000000   $k1: 00000000
   $gp: 00000000   $sp: 7fffeac8   $fp: 00000000   $ra: 00400188
    pc: 004000d4    hi: 00000000    lo: 00000000

Current instruction:    8e620000 (at 004000d0)

Decoded instruction:  lw        $v0, 0($s3)     (0x10000054)
我已经花了很多时间单步调试并手动跟踪寄存器,但我很难确定内存中的问题在哪里。它列出的指令是当我读取getElement中的内存时,但我不确定如何访问我不应该访问的内存。我想知道是否有人注意到getElement或printTop在访问内存方面有什么问题

# Name:         getElement
#
# Description:  Gets the value at the specified coordinates in the puzzle.
#
# Arguments:    a0      The x-coordinate
#               a1      The y-coordinate
#               a2      The size n
#
# Returns:      The element at array[n * row + col]
#

getElement:

    addi    $sp, $sp, -FRAMESIZE_24
    sw      $ra, 16($sp)
    sw      $s3, 12($sp)
    sw      $s2, 8($sp)
    sw      $s1, 4($sp)
    sw      $s0, 0($sp)

    move    $s0, $a2                # store n
    move    $s1, $a0                # store row
    move    $s2, $a1                # store col
    la      $s3, puzzle             # get address of array

    mul     $t0, $s0, $s1           # n * row
    add     $t1, $t0, $s2           # (n * row) + col
    sll     $t1, $t1, 2
    add     $s3, $s3, $t1
    lw      $v0, 0($s3)

    lw      $ra, 16($sp)
    lw      $s3, 12($sp)
    lw      $s2, 8($sp)
    lw      $s1, 4($sp)
    lw      $s0, 0($sp)
    addi    $sp, $sp, FRAMESIZE_24
    jr      $ra

# Name:         printTop
#
# Description:  Prints the top of each "row" for a given cell in a row.
#               Ex:
#                       +---+
#               top ->  |\##|
#                       |#\#|
#                       |##\|
#                       +---+
#
# Arguments:    a0      The array containing the cells in the puzzle
#               a1      The size n
#               a2      The current row
#
# Returns:      Nothing
#

printTop:

    addi    $sp, $sp, -FRAMESIZE_20
    sw      $ra, 12($sp)
    sw      $s2, 8($sp)
    sw      $s1, 4($sp)
    sw      $s0, 0($sp)

    move    $s0, $a0
    move    $s1, $a1
    move    $s2, $a2
    li      $t1, 0              # col = 0

    j       top_loop

top_loop:

    beq     $t1, $s1, top_done

    move    $a0, $s2
    move    $a1, $t1
    move    $a2, $s1
    jal     getElement

    # if empty
    beq     $v0, $zero, t_empty

t_empty:

    # print "   |"
    li      $v0, PRINT_STRING
    la      $a0, empty
    syscall

    addi    $t1, $t1, 1

    j       top_loop

top_done:

    lw      $ra, 12($sp)
    lw      $s2, 8($sp)
    lw      $s1, 4($sp)
    lw      $s0, 0($sp)
    addi    $sp, $sp, FRAMESIZE_20
    jr      $ra
编辑:我一直在修补一些代码,我认为它非常接近工作。在使用printTop之前,我将大小n减去1,然后将
beq$t1,$s1,top_done
更改为
bgt$t1,$s1,top_done
,现在我得到的输出是:

+---+---+
|   |   |
太棒了!除此之外,我还只是在main中直接调用printTop进行测试,所以当我在循环中实际运行它时,我得到以下结果:

+---+---+
|   |   |
|
|
+---+---+
|   |
|
|
+---+---+

出于某种原因,第二行只打印一个单元格,但看起来我不再访问不存在的内存了。有没有关于这是什么原因的想法?

查看寄存器转储:

$s0: 00000002   $s1: 00000000   $s2: 00000015   $s3: 10000054
s2看起来可疑,因为它应该是列-我希望是0或1。 a1,从中设置的是相同的值,在printTop中从t1设置

尽管t1在printTo中看起来是ok的,但对于col来说,它并没有保存,但寄存器也在getElement中使用


因此,问题的一个原因是t1由于多种原因被用于多个函数。

我觉得自己太笨了。我把代码改回原来的样子,只是用getElement中使用的t寄存器替换了s寄存器,现在可以正常工作了。非常感谢你的帮助!作为将来的参考,我应该在什么时候使用s寄存器vs t寄存器?只使用其中一个而不使用另一个会是一种不好的做法吗?就像我尝试在执行操作时使用t寄存器一样,但这显然会导致问题。请参阅t vs s寄存器