Проблемы адресации памяти с двумерным массивом, реализованным как одномерный массив (MIPS) - PullRequest
0 голосов
/ 20 ноября 2018

Я пытаюсь представить 2D-головоломку как одномерный массив. В настоящее время я пытаюсь проверить простую головоломку 2х2 с пустыми ячейками. В 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

Редактировать: Я возился с некоторыми кодами и очень близко подошел к работе. Я вычел размер n на 1, прежде чем перейти в printTop, и изменил beq $t1, $s1, top_done на bgt $t1, $s1, top_done, а теперь получаю следующий вывод:

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

Что здорово! За исключением того, что я также просто тестировал с вызовом printTop непосредственно в main, поэтому, когда я фактически запускаю его в цикле, я получаю это:

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

По какой-то причине во втором ряду печатается только одна ячейка, но похоже, что я больше не обращаюсь к несуществующей памяти. Любые идеи относительно того, что является причиной этого?

1 Ответ

0 голосов
/ 20 ноября 2018

Глядя на дамп регистра:

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

s2 выглядит подозрительно, так как он должен быть столбцом - я бы ожидал 0 или 1. a1, откуда он установлен, является тем же значением и находится в процессеустановить из t1 в printTop

, и хотя t1 выглядит нормально, увеличиваясь в printToo для col, он не сохраняется, но регистр также используется в getElement

Таким образом, одной причиной проблемы являетсяt1 используется в нескольких функциях по нескольким причинам.

...