在研究编译器优化时,我只是编写了以下代码:
#include<stdio.h>
struct fraction {
int num ;
int denum ;
};
int main()
{
struct fraction pi;
pi.num = 22;
pi.denum = 7;
return 0;
}
使用
gcc test.c -o test
当我拆开它时,我得到:
push %ebp
mov %esp,%ebp
sub $0x10,%esp
movl $0x16,-0x8(%ebp)
movl $0x7,-0x4(%ebp)
mov $0x0,%eax
leave
ret
但如果我应用以下优化:
gcc test.c -o test -O3
我所有的反汇编是:
push %ebp
xor %eax,%eax
mov %esp,%ebp
pop %ebp
ret
在没有优化的情况下,值22和7在反汇编中清晰可见,我可以清楚地理解代码是如何工作的,但优化后现在这些值在哪里?代码现在如何工作?请有人解释一下。
答案 0 :(得分:12)
由于您的代码无法有效地执行外部可见的任何会产生不可预测副作用的内容,因此结构的创建只需完全消除,现在您的所有代码都会返回0 main()
。
(如果你告诉编译器它确实需要创建结构,因为它可能被别人/其他人修改,它就不会删除代码。将变量声明为volatile
你会在汇编程序中看到它。)
答案 1 :(得分:4)
编译器确定pi
从未在该范围之外使用,并且由于没有副作用,因此优化了整个变量以及分配。
生成的汇编代码几乎将0
加载到eax
中,摆弄堆栈指针,然后返回。