Mips 到 C 的翻译,两个 for 循环
Mips to C translation, two for-cycles
我最近开始研究 MIPS,但我不确定我是否理解这段代码。
addi s4, [=10=], 0 // s4 = 0;
addi s1, [=10=], 7 // s1 = 7;
addi t2, [=10=], 7 // t2 = 7;
addi s0, [=10=], 1 // s0 = 1;
addi t1, [=10=], 21 // t1 = 21;
L1: addi s1, [=10=], 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, [=10=], 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, [=10=], 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, [=12=], 0
在我看来我重写了 s1 = 7; s1 = 0;。这种情况是在 L1 的每次迭代中发生还是只发生一次?我问的原因是因为行 L2: addi s4, s4, 7
发生在 L2 循环的每次迭代中。
由于我的假设,我不确定我对 C 的翻译是否正确。预先感谢您澄清这段代码中发生的事情。
正如 Jester 在评论中回答的那样,s1 = 0;
每次迭代都会发生。
C 翻译有点正确,但更准确的 C 版本应该是:
s4 = 0;
s1 = 7;
s0 = 1;
do {
s1 = 0;
do {
s4 += 7;
} while (++s1 < 7);
} while (++s0 < 21);
这应该会在您的情况下产生相同的结果,但不同之处在于 for
与 do ... while
循环的原理,其中 for
在执行之前进行第一次检查第一次迭代,而 do ... while
确实至少执行一次 body 语句,即使条件是 false
从一开始也是如此。
汇编中的 for
通常在循环代码的开头有比较 + 条件分支,并以无条件分支结束回到那个开始(至少在考虑到可读性的人写的时候, C/C++ 编译器可能会为了性能稍微展开它,甚至在编译时计算稳定时预先计算一些部分,就像这个 - 一个好的 C 编译器会把它编译成 return 980;
).
MIPS gcc 5.4 (-O3) 至少 godbolt.org 会产生:
j
li ,980 # 0x3d4
我最近开始研究 MIPS,但我不确定我是否理解这段代码。
addi s4, [=10=], 0 // s4 = 0;
addi s1, [=10=], 7 // s1 = 7;
addi t2, [=10=], 7 // t2 = 7;
addi s0, [=10=], 1 // s0 = 1;
addi t1, [=10=], 21 // t1 = 21;
L1: addi s1, [=10=], 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, [=10=], 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, [=10=], 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, [=12=], 0
在我看来我重写了 s1 = 7; s1 = 0;。这种情况是在 L1 的每次迭代中发生还是只发生一次?我问的原因是因为行 L2: addi s4, s4, 7
发生在 L2 循环的每次迭代中。
由于我的假设,我不确定我对 C 的翻译是否正确。预先感谢您澄清这段代码中发生的事情。
正如 Jester 在评论中回答的那样,s1 = 0;
每次迭代都会发生。
C 翻译有点正确,但更准确的 C 版本应该是:
s4 = 0;
s1 = 7;
s0 = 1;
do {
s1 = 0;
do {
s4 += 7;
} while (++s1 < 7);
} while (++s0 < 21);
这应该会在您的情况下产生相同的结果,但不同之处在于 for
与 do ... while
循环的原理,其中 for
在执行之前进行第一次检查第一次迭代,而 do ... while
确实至少执行一次 body 语句,即使条件是 false
从一开始也是如此。
汇编中的 for
通常在循环代码的开头有比较 + 条件分支,并以无条件分支结束回到那个开始(至少在考虑到可读性的人写的时候, C/C++ 编译器可能会为了性能稍微展开它,甚至在编译时计算稳定时预先计算一些部分,就像这个 - 一个好的 C 编译器会把它编译成 return 980;
).
MIPS gcc 5.4 (-O3) 至少 godbolt.org 会产生:
j
li ,980 # 0x3d4