在家庭作业中,我接到一个任务,要将C代码改为ASM的simplifiedDLX:
a = 0;
for (i = 1; i < 14; i++)
a = a + c;
A[0] = a;
我的解决方案:
假设:
a
的值在寄存器R1中c
的值在寄存器R2中i
的值在寄存器R3中地址值
A
(表示&A
)在寄存器R4中然后:
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
他们的解决方案:
假设:
a
的值在寄存器R1中i
的值在寄存器R2中(注意此处的更改)c
的值在寄存器R3中(注意此处的更改)地址值
A
(表示&A
)在寄存器R4中然后:
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
。如果
True
:在循环中应用命令,否则:退出循环。
增量变量
返回#2
所以他们的代码不同于for循环算法,因为它在初始化后不检查条件(#2)。。。
我心想,这是优化的结果吗?
这是什么级别的优化?(IIRC有4个水平:O0、O1、O2、O3)
在解释C代码时,默认情况下是否需要优化代码?
最佳答案
当优化被激活时,编译器会检查它的汇编代码,以查看是否有需要改进的地方,特别是避免无用的指令或检查。
例如,在您的代码中,for
循环是一个初始化循环,然后是一个经典的while
循环。一个典型的优化是检查第一个条目的while
条件是否可以为false,如果不能,则在do while
循环中转换它。
这正是你的情况。i < 14
不能为false,如果您在指令后面选中它,表示i = 1
。所以跑起来更快:
a = 0;
i = 1;
do
{
a = a + c;
i++;
} while (i < 14);
A[0] = a;
是的,这是一种优化。但是,当您直接用汇编语言编写代码时,通常需要使用这种技巧,因为汇编编程(主要是学习)的目标是使您的代码尽可能快,使用任何可能的方法减少指令调用。
这是GCC上O1级优化的结果。
关于c - ASM-优化的`for`循环,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32808149/