Итак, у меня есть вопрос об адресации массива в 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