为什么gcc会生成冗长的汇编代码?
为什么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)
为什么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函数。