Mips到C的翻译,两个for-cycles

时间:2017-08-01 13:31:01

标签: c mips

我最近开始探索MIPS,我不确定我是否理解这段代码。

  addi s4, $0, 0    // s4 = 0; 
  addi s1, $0, 7    // s1 = 7;
  addi t2, $0, 7    // t2 = 7;
  addi s0, $0, 1    // s0 = 1;
  addi t1, $0, 21   // t1 = 21;
L1: addi s1, $0, 0  // s1 has new value s1 = 0;?
L2: addi s4, s4, 7  // s4 += 7;
  addi s1, s1, 1    // s1 += 1;
  slt t3, s1, t2    // t3 = (s1 < t2) ? 1 : 0;
  bne t3, $0, L2    // if t3 != 0 go to L2 
  nop
  addi s0, s0, 1    // s0 =+ 1;
  slt t3, s0, t1    // t3 = (s0 < t1) ? 1 : 0; 
  bne t3, $0, L1    // if t3 != 0 go to L1
  nop
L3: nop

问题是这个汇编程序代码末尾s4的值是多少。 我想C翻译将是:

for(int i = 1; i < 21; i++)
   for(int j = 0; j < 7; j++)
      s4 += 7;

但是我关心这一行。

L1: addi s1, $0, 0

在我看来,我越过s1 = 7; s1 = 0;这是在L1上的每次迭代还是只发生一次?我问的原因是因为行L2: addi s4, s4, 7在L2周期的每次迭代中都会发生。

我不确定如果由于我的假设,我对C的翻译是正确的。提前感谢您澄清此代码中发生的情况。

1 个答案:

答案 0 :(得分:1)

正如Jester在评论中回答的那样,s1 = 0;每次迭代都会发生。

C转换是正确的,但更准确的C版本将是:

s4 = 0;
s1 = 7;
s0 = 1;
do {
    s1 = 0;
    do {
        s4 += 7;
    } while (++s1 < 7);
} while (++s0 < 21);

这应该会在您的情况下产生相同的结果,但区别在于for vs do ... while循环的原则,其中for在执行第一次迭代之前进行第一次检查,尽管do ... while确实至少执行一次body语句,即使条件从开始就是false

程序集中的for通常在循环代码的开头有比较+条件分支,并以无条件分支结束回到该开始(至少在人类编写时考虑到了可读性,C / C ++编译器当计算在编译时稳定时,可以为性能展开一些甚至预先计算一些部分,就像这样 - 一个好的C编译器会把它编译成return 980;)。

MIPS gcc 5.4(-O3)的至少godbolt.org确实产生了:

    j       $31
    li      $2,980                  # 0x3d4