实现为1D阵列(MIPS)的2D阵列的内存解决问题

时间:2018-11-20 01:37:58

标签: mips memory-address

我试图将2D拼图表示为1D数组。目前,我正在尝试测试一个带有空单元格的简单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进行测试外,所以当我实际在循环中运行它时,会得到以下信息:

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

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

1 个答案:

答案 0 :(得分:0)

查看寄存器转储:

$s0: 00000002   $s1: 00000000   $s2: 00000015   $s3: 10000054

s2似乎是可疑的,因为它应该是该列-我期望0或1。 a1,从那里设置的是相同的值,并且是在printTop中从t1设置的

尽管t1在col的printTooo中看起来可以递增,但它没有保存,但寄存器也用于getElement

造成此问题的唯一原因是出于多种原因在多种功能中使用了t1。