我最近开始探索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的翻译是正确的。提前感谢您澄清此代码中发生的情况。
答案 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