好的,我有一个关于在MIPS中寻址数组的问题。
让我们举个例子,我有类似的东西:
lw $t9,0($t5) # $t9 is an alias for some value in memory. Let's call it "var."
假设我想使用" var":
索引一个字节数组la $a0,array # Starting address of array in memory.
addi $t4,$a0,$t9 # Want to calculate address of array[var].
我收到算术溢出错误,我假设是因为我试图将一个字的值添加到数组的地址。
如果以上内容没有意义,这是我的实际代码。我正在尝试将C函数转换为MIPS:
for (int i = 0; i < 256; i++) {
pair_table[i] = 0;
is_closer[i] = false;
}
for (int i = 0; pairs[i]; i += 2) {
const char op = pairs[i];
const char cl = pairs[i+1];
is_closer[cl] = true;
pair_table[op] = cl;
}
这是我的MIPS翻译。我相信这是我如何区分单词和字节,因为如果我使用lb而不是lw,代码将执行。但是,输出是错误的,因为我需要整个字而不是一个字节。我的问题是如何将字值实际索引为数组的索引?
la $a0,pair_table # $a0 will hold address of pair_table.
addi $a1,$0,256 # $a1 will hold size of tables (256) for both pair_table and is_closer.
move $t1,$0 # Set $t1 to 0 (serves as counter for number of entries in table; can't have over 256).
move $t2,$0 # Set $t2 to 0 (serves as counter for number of times branch to filltable has occurred).
filltable:
sb $0,0($a0) # current location in table set to 0 (0 also serving as false in is_closer's case)
addi $a0,$a0,1 # Increment current address of table by 1.
addi $t1,$t1,1 # Increment number of entries by 1.
slt $t3,$t1,$a1 # $t3 = (index total < 256)
bne $t3,$0,filltable # If (index total < 256), continue filling table.
nop
bgtz $t2,setpairs # If $t2's count is greater than 0, both pair_table and is_closer are filled. Time to fill pairs table.
nop
la $a0,is_closer # $a0 holds address of is_closer.
move $t1,$0 # Reset $t1 to 0 (counter for number of table entries).
addi $t2,$t2,1 # Increment filltable counter by 1.
addi $t4,$0,1 # $t4 will hold the value 1 (true in this case).
sb $t4,0($a0) # Store "true" in the first entry of is_closer.
addi $a0,$a0,1 # Go to next location in is_closer.
addi $t1,$t1,1 # Increment number of entries by 1.
b filltable # Continue filling rest of is_closer table entries with 0 (false).
nop
setpairs:
la $a0,pairs # Get address of pairs table.
move $t1,$0 # Start at index 0.
fillpairs:
sll $t2,$t1,2 # $t2 = current index * 4
add $t0,$a0,$t2 # $t0 = address of pair at index
lb $t9,0($t0) # Get value of pairs[index]. //op//
# lw $t9,0($t0) ####################
addi $t0,$t0,4 # Get next location in pairs (pairs[index+1]).
lb $t3,0($t0) # Get value of pairs[index+1]. //cl//
# lw $t3,0($t0) ####################
la $a1,is_closer # Get starting address of is_closer table.
add $t6,$a1,$t3 # Get address of is_closer[cl].
sb $t4,0($t6) # Set is_closer[cl] to true (1).
# sw $t4,0($t6)
la $a2,pair_table # Get starting address of pair_table.
add $t5,$a2,$t9 # Get address of pair_table[op].
sb $t3,0($t5) # pair_table[op] = cl
# sw $t3,0($t5) #####################
addi $t1,$t1,2 # index += 2
bnez $t9,fillpairs # If pairs[i] ($t9) not yet NULL terminated, continue filling the table.
nop
jr $ra
nop
答案 0 :(得分:1)
假设您的pairs
是一个4字节整数数组,如果过于复杂,您的代码看起来是正确的。一个问题是你在循环体之后检查终止条件,但C版本在正文之前进行测试。
对于算术溢出,您应该使用不生成该错误的addiu
/ addu
。你有可能在某个地方遇到问题。
像往常一样,您应该使用调试器/模拟器来逐步执行代码并查看它出错的地方。