0

例如,我有一段 C 代码,我正在尝试转换为 MIPS 进行练习,但是对于变量计数,我不知道是使用 addi $t0,0 还是 li $t0, 0。我可以使用要么要么?有什么区别?

   Void haarPredict (int vector[], int N) 
    { 
        int half = N >> 1; 
        int count = 0; 

        for(int i = 0; i < half; i++) 
        { 
            int predictVal = vector[i]; 
            int j = i + half; 
            vector[j] = vector[j] - predictVal 
        } 
    } 

这是我将上述代码转换为 MIPS 后所拥有的。假设 $a0 是 vector[] 而 $a1 是 N。同样,我不确定 li 或 addi 是否正确使用。

      srl $t0, $a1, 1     #t0 holds half. half = N >> 1
      addi $t1, $t1, 0    #t1 holds count. count = 0
      addi $t2, $t2, 0    #t2 holds i. i = 0
loop: slt $t3, $t2, $t0     #t3 holds 1 if i < half
      beg $t3, $zero, exit  #exit if t3 == 0
      lw  $t4, 0($a0)       #t4 holds predictValue
      addi $a0, $a0, 4    #4 bytes for next word address
      addi $t5, $t2, $t0  #t5 holds j. j = i + half
      lw $t6, $t6, $t4    #vector[j]=vector[j]-predivtVal
      addi $t2, $t2, 1    #i++
      j loop
exit: jr $ra
4

1 回答 1

2

li (立即加载)指令将特定数值加载到寄存器中。

addi (Add inmediate) 将一个寄存器和一个符号扩展的立即相加,并将结果存储在一个寄存器中。

因此,除非您 100% 确定寄存器的值为零,否则您不应该使用addi指令来设置寄存器。

例如:

addi $t1, $t1, 0    #t1 holds count. count = 0

您不知道 $t1 在那个特定时刻是否为零。如果那是一个子例程,您可能正在使用 $t1 的垃圾值(在调用子例程之前,在跳转到子例程地址之前的值)。

所以安全的方法是用li设置寄存器(因此,count=0),而不考虑寄存器的先前值。

于 2018-10-14T22:41:22.493 回答