Как использовать слово для индексации массива байтов в MIPS?

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

person Jazzy Fresh    schedule 01.07.2014    source источник


Ответы (1)


Предполагая, что ваш pairs представляет собой 4-байтовый целочисленный массив, ваш код выглядит правильно, если он слишком сложен. Одна проблема заключается в том, что вы проверяете условие завершения после тела цикла, но версия C проверяет перед телом.

Что касается арифметического переполнения, вы должны использовать addiu/addu, которые не генерируют эту ошибку. Скорее всего, у вас все же есть проблема где-то.

Как обычно, вы должны использовать отладчик/симулятор, чтобы просмотреть код и посмотреть, где что-то пойдет не так.

person Jester    schedule 01.07.2014
comment
Сделаю. Я выложу свой код решения, когда закончу, если кому-нибудь когда-нибудь понадобится ссылка. Я не видел много примеров массивов в MIPS, где вы используете индекс так, как я их использую. Я использую другие переменные в качестве индексов. - person Jazzy Fresh; 02.07.2014
comment
Кроме того, просто добавленное примечание: условие завершения должно быть хорошо для проверки после тела цикла. По сути, он делает то же самое. Было бы довольно отвратительно в коде поместить b fillpairs, разветвить резервную копию, а ЗАТЕМ выполнить проверку, если пара [i] верна. По сути, я делаю то же самое. На самом деле, я думаю, что в MIPS довольно стандартно проверять условия цикла в конце; затем разветвитесь, если условие все еще выполняется. Это не имеет значения и занимает меньше строк кода. - person Jazzy Fresh; 02.07.2014
comment
В общем случае имеет значение, выполняете ли вы тело цикла, даже если условие завершения уже истинно. В вашем случае это может не иметь значения, но это все равно не расшифровка кода C. Обратите внимание, что ассемблерный код установит is_closer[pairs[i+1]] в значение true, где i+1 находится за терминатором. Код C никогда не использует этот элемент, он может быть вне допустимого диапазона или содержать мусор. - person Jester; 02.07.2014
comment
О, хорошо, я понимаю, что ты имеешь в виду. Я посмотрю на это. Как я уже сказал, я собираюсь еще немного поиграть с кодом, но я обязательно опубликую готовый продукт для любых других новичков в MIPS. Спасибо за ваши комментарии и помощь! - person Jazzy Fresh; 02.07.2014