将C for循环转换为MIPS

问题描述 投票:4回答:2

我正在尝试将此C代码直接翻译为mips,而不修改任何指令,以使其更好地运行:

for(i = 0; i != j; i += 2)
    b[i] = a[i] - a[i + 1]

我真的不打算用mips编写代码,我只是想了解一些事情。这是我到目前为止(不多):

#t5 = i
$t6 = j
#t1 = a
#t2 = b
#t3 = c
#t10, t11, t12 = free

add $t5, $zero, $zero # initialize i = 0 

loop:
    bne $t5, $t6        # check if i is not equal to j
    addi $t5, $t5, 2    # i += 2
    add $t10, $t5, $t11 # temp reg $t10 = address of b[i]
    lw $t2, 0($t10)     # temp reg $t2 = b[i]
    add $t10, $t5, $t12 # temp reg $t10 = address of a[i]
    lw $t1, 0($t10)     # temp reg $t1 = a[i]

不确定bne是否正确,因为我没有指定任何分支到。我已经阅读了mips中的数组,但它让我感到困惑。我知道在将数组放入寄存器时,我需要使用适当的偏移量进行字节寻址。它是否与变量而不是数组中的数字相同?任何方向或提示都会很好。谢谢!

c for-loop mips
2个回答
1
投票

你猜对了,需要一个分支的位置。因此,您的程序中至少需要一个标记。在下面的示例中,该新标记称为“exit”。

至于加载和存储中的寻址,我同意你的看法;它起初可能会有点混乱(特别是如果你习惯于c样式数组索引)。如果您的偏移量不是常量,则必须执行添加(或减法)操作以获取地址。让我们使用[i + 1]的地址作为示例:首先,您需要将a的地址添加到i并将其存储在某处,然后您可以使用常量偏移量加载(或存储)到真实地址。我重写了你的例子,以便你可以看到我在说什么;这是通过例子比通过解释更容易看到的事情之一:)

#t5 = i
#t6 = j
#t1 = address of a
#t2 = address of b
#t10, t11, t12 = free

#START
move $t5,$0               #set $t5 to zero

loop:
       bne $t5,$t6,exit   #if $t5 not equal to $t6 branch to exit
       addi $t10,$t1,$t5  #temp reg $t10 = address of a[i]
       lw $t11,1($t10)    #temp reg $t11 = a[i + 1]
       lw $t12,0($t10)    #temp reg $t12 = a[i]
       sub $t10,$t12,$t11 #temp reg $t10 = a[i] - a[i + 1]
       addi $t11,$t2,$t5  #temp reg $t11 = address of b[i]
       sw $t10,0($t11)    #store word b[i] = a[i] - a[i + 2]
       addi $t5,$t5,2     #i+=2
       j loop             #jump to start of loop
exit:

1
投票

不要忘记,对于字读取,存储器寻址偏移4位。根据计算机组织和架构的文本,在i索引的数组中移动的正确方法是:

sll $t10,$t5,2     #$t10=i*4
add $t10,$t10,$t1  #$t10 = i*4 + addr(a)
lw $t11,4($t10)    #temp reg $t11 = a[i + 1]
lw $t12,0($t10)    #temp reg $t12 = a[i]

请注意,我必须乘以4,并且lw的偏移量应该是4的倍数。如果不这样做,寻址将无法正常进行,因为寻址是按字节顺序的,但我们使用的是逐字数据操作。正确的实现看起来像这样。

#t5 = i
#t6 = j
#t1 = address of a
#t2 = address of b
#t10, t11, t12 = free

#START
move $t5,$0               #set $t5 to zero

loop:
       bne $t5,$t6,exit   #if $t5 not equal to $t6 branch to exit
       sll $t10,$t5,2     #temp reg $t10 = i*4
       add $t10,$t10,$t1 #temp reg $t10 = address of a[i]
       lw $t11,4($t10)    #temp reg $t11 = a[i + 1]
       lw $t12,0($t10)    #temp reg $t12 = a[i]
       sub $t10,$t12,$t11 #temp reg $t10 = a[i] - a[i + 1]
       sll $t11,$t5,2     #temp reg $t11 = i*4
       add $t11,$t11,$t2  #temp reg $t11 = address of b[i]
       sw $t10,0($t11)    #store word b[i] = a[i] - a[i + 2]
       addi $t5,$t5,2     #i+=2
       j loop             #jump to start of loop
exit
© www.soinside.com 2019 - 2024. All rights reserved.