【问题标题】:How is code working after Optimising?优化后的代码如何工作?
【发布时间】:2013-05-10 17:23:40
【问题描述】:

在研究编译器优化时,我简单地编译了以下代码:

#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 在反汇编中清晰可见,我可以清楚地理解代码是如何工作的,但是优化后这些值现在在哪里?代码现在如何工作?请有人解释一下。

【问题讨论】:

  • 代码基本上什么都不做,编译器知道这一点。
  • “denum”是指“denum”吗? “有”是指“没有”吗?我知道已经很晚了,但是在谈论编译器优化时注意细节有点重要......
  • 你的程序什么也没做;优化器发现了这一点并将其更改为什么都不做(但返回 0)的程序
  • 明白,谢谢@antlersoft

标签: c linux compiler-construction disassembly


【解决方案1】:

由于您的代码没有有效地执行任何会产生不可预测的副作用的外部可见操作,因此结构的创建被简单地完全消除,现在您的代码所做的只是从 @987654321 返回 0 @。

(如果你告诉编译器它确实需要创建结构,因为它可能被某人/其他东西修改,它不会摆脱代码。将你的变量声明为volatile,你会在汇编器中查看。)

【讨论】:

  • 或打印或退回。对需要在程序之外产生影响的值做一些事情。
【解决方案2】:

编译器确定 pi 从未在该范围之外使用,并且由于没有副作用,因此优化了整个变量以及赋值。

生成的汇编代码几乎将0 加载到eax,摆弄堆栈指针,然后返回。

【讨论】:

    猜你喜欢
    • 2021-03-19
    • 2022-11-23
    • 2021-06-23
    • 2012-09-18
    • 2021-02-14
    • 2015-09-19
    • 2011-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多