在 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 次迭代,您将能够发现问题。
我有一个 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 次迭代,您将能够发现问题。