如何在MIPS中使用单词索引字节数组?

时间:2014-07-01 17:48:54

标签: assembly indexing bytearray word 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

1 个答案:

答案 0 :(得分:1)

假设您的pairs是一个4字节整数数组,如果过于复杂,您的代码看起来是正确的。一个问题是你在循环体之后检查终止条件,但C版本在正文之前进行测试。

对于算术溢出,您应该使用不生成该错误的addiu / addu。你有可能在某个地方遇到问题。

像往常一样,您应该使用调试器/模拟器来逐步执行代码并查看它出错的地方。