为什么gcc会生成冗长的汇编代码?

11 浏览
0 Comments

为什么gcc会生成冗长的汇编代码?

我对GCC生成的汇编代码(-S选项)有一个问题。\n由于我对汇编语言还不熟悉,了解甚少,所以问题可能很基础。但我仍然希望有人能回答:\n假设我有以下C代码:\n

main(){
    int x = 15; 
    int y = 6;
    int z = x - y;
    return 0;
}

\n如果我们查看汇编代码(特别是与int z = x - y相对应的部分),我们可以看到:\nmain:\n

...
subl    $16, %esp
movl    $15, -4(%ebp)
movl    $6, -8(%ebp)
movl    -8(%ebp), %eax
movl    -4(%ebp), %edx
movl    %edx, %ecx
subl    %eax, %ecx
movl    %ecx, %eax
movl    %eax, -12(%ebp)
...

\n为什么GCC不生成像下面这样的代码,这样可以减少拷贝操作。\nmain:\n

...
movl    $15, -4(%ebp)
movl    $6, -8(%ebp)
movl    -8(%ebp), %edx          
movl    -4(%ebp), %eax          
subl    %edx, %eax              
movl    %eax, -12(%ebp)
...

\n附注:\nLinux zion-5 2.6.32-21-generic #32-Ubuntu SMP Fri Apr 16 08:10:02 UTC 2010 i686 GNU/Linux\ngcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)

0
0 Comments

为什么gcc会生成冗长的汇编代码?

首先,正如Mysticial所评论的那样,您应该打开一些优化选项。尝试向gcc传递-O2(或-O3,或只是-O1)。如果您想更好地理解生成的汇编代码,还可以传递-fverbose-asm。如果您想了解代码是如何生成(或未生成)的原因,请学习GCC内部结构(可能还要传递-fdump-tree-all和-fdump-rtl-all,这会产生大量的内部转储文件)。

关于MELT(MELT是一种用于扩展GCC的特定领域语言)的一些幻灯片可能会有所帮助,并提供其他参考资料。

当要求时,您可能会对GCC提供的优化程度感到惊讶。默认情况下,GCC不进行优化。有一些优化是您应该明确要求的(甚至在-O3级别上也不会执行)。

最新版本的GCC可能比旧版本进行更多优化。2021年的当前GCC版本是GCC 11。

PS.我不再在MELT上工作(在2017年放弃了它)。在2021年,还可以参考Bismon、RefPerSys、Frama-C。

我还推荐在-fdump-tree-all之外,还使用-fdump-rtl-all,它会用内部GCC表示对汇编输出进行注释。

这让我想起了我曾经有一个计算向量范数的函数。当查看gcc如何进行优化时,我得到了以下结果(输入是常量):-O1:函数内联,-O2:循环也展开了,-O3:常量向量的范数在代码中静态地出现,根本没有计算。(可能把-O1和-O2搞混了)

MELT网站目前看起来像是垃圾网站,URL改变了吗?

已更正。我添加了一条指向某个存档的链接。

äfer:如果您想看到gcc如何计算某个东西,请不要提供常量输入。只需编写一个接受参数并返回值的函数。请参阅《如何从GCC/clang汇编输出中去除“噪音”?》。如果您想查看汇编代码而不是运行它,您不需要一个main函数。

0