Assembly 在MIPS中迭代数组

Assembly 在MIPS中迭代数组,assembly,mips,Assembly,Mips,我在MIPS中有一个数组,我正在尝试迭代它 当我想要获取特定数组单元格的值时,此代码可以工作,但当我尝试循环时,它会抛出地址超出范围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, 1

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

当我想要获取特定数组单元格的值时,此代码可以工作,但当我尝试循环时,它会抛出
地址超出范围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
的分支,它不使用循环,但正如我所说的,它使用相同的精确代码来查找数组的索引,并使用
syscall
打印它,工作得非常好


我在某处发现了一个代码片段,它使用
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次迭代,就可以发现问题。

在调试器中完成这一步,您将看到错误

在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递增,因此它不会达到循环退出条件,最终它将在尝试使用非常非常大的索引从内存加载错误地址时崩溃


但是,如果你只需要重复两次代码,你就可以发现问题。

你现在更新
$t1
的方式意味着你将在进行过程中累积所有索引。更改
添加$t1、$t2、$t3以使用另一个寄存器作为其目标,然后使用该寄存器作为
lw
的地址,或者删除循环的前三行并放置一个
addi$t1、$t1,4
就在
j loop
之前。您现在更新
$t1
的方式意味着您将在执行过程中累积所有索引。要么更改
添加$t1、$t2、$t3
以使用另一个寄存器作为其目标,然后使用该寄存器作为
lw
的地址,要么删除循环的前三行,并在
j循环之前添加一个
addi$t1、$t1、4
。是的,我不敢相信我没有注意到这一点。诸如此类的事,伙计……真不敢相信我竟然没注意到。像这样的事情,伙计。。。