在作业中,我收到了将C代码更改为简化DLX的ASM的任务:
multi
假设:
a = 0;
for (i = 1; i < 14; i++)
a = a + c;
A[0] = a;
的值在寄存器R1 a
的值在寄存器R2 c
的值在寄存器R3 i
的地址值(表示A
)在寄存器R4 然后:
&A
假设:
addi R1 R0 0 // init a = 0
addi R3 R0 1 // init i = 1
slti R5 R3 14 // test (i < 14) ; R5 = 1 if i < 14
beqz R5 3 // branch 3 lines of R5 == 0
add R1 R1 R2 // a = a + c
addi R3 R3 1 // i++
beqz R0 -5 // return up to the condition of the for loop
sw R1 R4 0 // A[0] = 0
的值在寄存器R1 a
的值在寄存器R2 中(请注意此处的更改) i
的值在寄存器R3 中(注意此处的更改) c
的地址值(表示A
)在寄存器R4 然后:
&A
他们的解决方案显然更好,因为命令少了一个 - 我的代码有一个额外的条件分支。他们的代码正是我想要做的第一个,但后来我回忆起addi R1 R0 0 // a = 0
addi R2 R0 1 // i = 1
add R1 R1 R3 // a = a+c
addi R2 R2 1 // i++
slti R5 R2 14 // R5=1 iff i<14
bnez R5 -4 // jump 4 lines up from the next line if
// R5!=0, that is if i<14
sw R1 R4 0 // store the new value of A[0]=a (R1)
循环算法:
for
如果True
:在循环中应用命令,所以他们的代码与for循环算法不同,因为它在初始化(#1)后没有检查条件(#2)...
我心想 - 这是优化的结果吗?
这是什么级别的优化? (IIRC有4个级别:O0,O1,O2,O3)
在解释C代码时,是否应该默认优化代码?
答案 0 :(得分:2)
激活优化后,编译器会检查其汇编代码,以查看是否有任何需要改进的地方,特别是避免无用的指令或检查。
例如,在您的代码中,for
循环是初始化,然后是经典的while
循环。经典优化是检查第一个条目的while
条件是否为false,如果不是,则在do while
循环中对其进行转换。
这正是你的情况。如果您在指令i < 14
之后检查它,则i = 1
不能为假。所以运行得更快:
a = 0;
i = 1;
do
{
a = a + c;
i++;
} while (i < 14);
A[0] = a;
是的,这是一种优化形式。但是当你直接用汇编语言编写代码时,通常需要你做这种技巧,因为汇编编程的目标(主要是学习它)是尽可能快地使你的代码,使用任何减少指令调用的可能性。
这是GCC上O1级别优化的结果。