将MIPs指令转换为C并减少执行

时间:2014-02-04 05:25:44

标签: c assembly mips

假设c级整数j保存在寄存器$t1中,$s2保存名为total的c级整数,$s0保存基址整数数组vArray

    addi $t1, $0, $0
LOOP:
    lw $s1, 0($s0)
    add $s2, $s2, $s1
    addi $s0, $s0, 4 
    addi $t1, $t1, 1
    slti $t2, $t1, 100
    bne $t2, $s0, LOOP

我的解决方案:

我想我已经找到了C代码,应该是:

for (j = 0; j < 100; j++) {

    total = total + vArray[j];

}

然后问题问:重写循环以减少执行的MIPS指令的数量。

但是,我无法减少执行的MIP指令数量。对我来说,我认为MIPs指令已经基本完成了,我无法想出另一个不到七个执行步骤的解决方案。

在阅读了减量建议之后,我想出了这个,可能有点笨拙的逻辑。

addi $t1, $zero, 404
LOOP: 
subi $t1, $t1, 4
add $s0, $s0, $t1
lw $t2, 0($s0)
add $s2, $s2, $t2
bne $t1, $zero, LOOP 

4 个答案:

答案 0 :(得分:1)

在最小化指令方面,这是我能做的最好的事情:

  addi $t1, $s0, 400
LOOP:
  lw $s1, 0($s0)
  add $s2, $s2, $s1
  addi $s0, $s0, 4
  bne $s0, $t1, LOOP

答案 1 :(得分:0)

寄存器$ t1实际上不需要递增或检查。它用于知道你已经执行了100次,但是当$ s0增加了400时你也能想出来。

答案 2 :(得分:0)

也循环展开。即忘记整个循环增量的事情,只做100次添加和100次内存获取操作。

答案 3 :(得分:0)

如果你想要尽可能小的代码,我想这可能是这样的:

       add $s2, $0, $0     ; initialize sum to 0
       addi $t1, $s0, $400 ; compute pointer limit
LOOP:  lw $s1, 0($s0)      ; load one element
       addi $s0, $s0, 4    ; point to next element
       add $s2, $s2, $s1   ; cumulate result (away from lw to skip delay slot)
       bne $t2, $t1, LOOP  ; loop until pointer reaches limit
       nop                 ; delay slot of the branch

基本上,您使用指针值作为循环退出条件,而不是计算单独寄存器中的迭代。

如果你想利用延迟槽:

       add $s2, $0, $0     ; initialize sum to 0
       addi $t1, $s0, $400 ; compute pointer limit
LOOP:  lw $s1, 0($s0)      ; load one element
       addi $s0, $s0, 4    ; point to next element
       bne $t2, $t1, LOOP  ; loop until pointer reaches limit
       add $s2, $s2, $s1   ; cumulate result (in delay slot)

循环展开:

       add $s2, $0, $0     ; initialize sum to 0
       addi $t1, $s0, $400 ; compute pointer limit
LOOP:  lw $s1, 0($s0)      ; load first element
       addi $s0, $s0, 8    ; compute next block address
       add $s2, $s2, $s1   ; cumulate first element
       lw $s1, -4($s0)     ; load second element
       bne $t2, $t1, LOOP  ; loop until pointer reaches limit
       add $s2, $s2, $s1   ; cumulate second element

每次加载和累积现在需要3个周期,而上面的一步循环中只有4个。

没有必要进一步展开循环,因为你不能在少于3个指令周期(一个内存加载,一个延迟槽,一个累加)中执行加载和累加步骤。