在 MIPS 中遍历数组

Iterate over array in MIPS

我有一个 MIPS 数组,我正在尝试迭代它。

当我想获取特定数组单元格的值时,此代码有效,但当我尝试遍历它时,它会抛出带有 address out of range 0x10565554 的运行时。

.data
boardState: .word 
        0, 0, 0, 0, 0, 0, 0, 0,        
        0, 0, 0, 0, 0, 0, 0, 0,        
        1, 2, 3, 4, 5, 6, 7, 8,        
        9, 10, 11, 12, 13, 14, 15, 16, 
        0, 0, 0, 0, 0, 0, 0, 0,        
        0, 0, 0, 0, 0, 0, 0, 0,        
        0, 0, 0, 0, 0, 0, 0, 0,        
        0, 0, 0, 0, 0, 0, 0, 0,        
        17, 18, 19, 20, 21, 22, 23, 24,
        25, 26, 27, 28, 29, 30, 31, 32,
        0, 0, 0, 0, 0, 0, 0, 0,        
        0, 0, 0, 0, 0, 0, 0, 0         
.text

main:
    la $t3, boardState
    li $t2, 0
    li $t4, 63
    jal loop

loop:
    add $t2, $t2, $t2
    add $t2, $t2, $t2 #quadruple index
    add $t1, $t2, $t3 #add index/offset to array address

    lw $a0, 0($t1) #load word into $a0 ***this is where it throws the error***
    li $v0, 1      #load syscall for printing integer
    syscall

    beq $t2, $t4, exit #branches to a syscall 10 if array length is reached
    addi $t2, $t2, 1   #else iterates and jumps back to loop beginning
    j loop

我在这个名为 single 的分支下有一个不使用循环的分支,但就像我说的,它使用相同的精确代码来查找数组的索引,并使用 [= 打印它13=] 并且工作完美。

我在某处发现了一段使用 sll 来递增索引的代码片段,但我真的不知道如何使用 sll。我坚持使用这段代码,因为它适用于单个实例。

在调试器中单步执行此操作,您会看到错误。

在C语言中,代码大致是这样的:

for ( int t2 = 0; t2 != 63; t2++ ) {
    t2 *= 4;
    ...boardState[t2]...;
}

因此,循环控制变量增加了四倍并增加了。

因此,$t2 取这些值:0, 0, 1, 4, 5, 20, 21, 84, 85, 340, 341, 1364, 1365, 5460, 5461, ...

由于循环退出条件测试使用等式 (= 63) ,并且循环控制变量没有严格按 1 递增,因此它没有达到循环退出条件,最终它会在尝试加载时崩溃使用非常非常大的索引从地址错误的内存中获取。

但如果您单步执行代码 2 次迭代,您将能够发现问题。