简体   繁体   English

为什么具有不同gcc版本的简单C程序的汇编代码不同?

[英]Why assembly code is different for simple C program with different gcc version?

I'm understanding the basics of assembly and c programming. 我了解汇编和C编程的基础知识。

I compiled following simple program in C, 我用C编译了以下简单程序,

#include <stdio.h>

int main()
{
  int a;
  int b;
  a = 10;
  b = 88

  return 0;
}

Compiled with following command, 用以下命令编译,

gcc -ggdb -fno-stack-protector test.c -o test gcc -ggdb -fno-stack-protector test.c -o测试

The disassembled code for above program with gcc version 4.4.7 is: 使用gcc版本4.4.7的上述程序的反汇编代码为:

5                      push   %ebp
89 e5                   mov    %esp,%ebp
83 ec 10                sub    $0x10,%esp
c7 45 f8 0a 00 00 00    movl   $0xa,-0x8(%ebp)
c7 45 fc 58 00 00 00    movl   $0x58,-0x4(%ebp)
b8 00 00 00 00          mov    $0x0,%eax
c9                      leave
c3                      ret
90                      nop

However disassembled code for same program with gcc version 4.3.3 is: 但是,与gcc版本4.3.3相同的程序的反汇编代码为:

8d 4c 23 04     lea     0x4(%esp), %ecx
83 e4 f0        and     $0xfffffff0, %esp
55              push    -0x4(%ecx)
89 e5           mov     %esp,%ebp
51              push     %ecx
83 ec 10        sub      $0x10,%esp
c7 45 f4 0a 00 00 00 00 movl $0xa, -0xc(%ebp)
c7 45 f8 58 00 00 00 00 movl $0x58, -0x8(%ebp)
b8 00 00 00 00          mov $0x0, %eax
83 c4 10                add $0x10,%esp
59                      pop %ecx
5d                      pop %ebp
8d 61 fc                lea -0x4(%ecx),%esp
c3                      ret 

Why there is difference in the assembly code? 为什么汇编代码不同?
As you can see in second assembled code, Why pushing %ecx on stack? 在第二个汇编代码中可以看到,为什么将%ecx压入堆栈?
What is significance of and $0xfffffff0, %esp ? and $0xfffffff0, %esp含义and $0xfffffff0, %esp什么?

note: OS is same 注意:操作系统相同

Compilers are not required to produce identical assembly code for the same source code. 编译器不需要为相同的源代码生成相同的汇编代码。 The C standard allows the compiler to optimize the code as they see fit as long as the observable behaviour is the same. 只要可观察的行为相同,C标准就允许编译器按其认为合适的方式优化代码。 So, different compilers may generate different assembly code. 因此,不同的编译器可能会生成不同的汇编代码。

For your code, GCC 6.2 with -O3 generates just: 对于您的代码,带有-O3 GCC 6.2只会生成:

xor     eax, eax
ret

because your code essentially does nothing. 因为您的代码基本上什么都不做。 So, it's reduced to a simple return statement. 因此,它简化为简单的return语句。

To give you some idea, how many ways exists to create valid code for particular task, I thought this example may help. 为了给您一些想法,有多少种方法可以为特定任务创建有效的代码,我认为这个示例可能会有所帮助。

From time to time there are size coding competitions, obviously targetting Assembly programmers, as you can't compete with compiler against hand written assembly at this level at all. 有时会有大小编码竞赛,显然是针对汇编程序员的,因为在此级别上您根本无法与编译器竞争手写汇编。

The competition tasks are fairly trivial to make the entry level and total effort reasonable, with precise input and output specifications (down to single byte or pixel perfection). 竞赛任务相当琐碎,可以通过精确的输入和输出规范(最小到单字节或像素完美)来使入门水平和总精力变得合理。

So you have almost trivial exact task, human produced code (at the moment still outperforming compilers for trivial task), with single simple rule "minimal size" as a goal. 因此,您几乎要完成一些琐碎的精确任务,即人为生成的代码(目前仍胜过琐碎任务的编译器),并以一个简单的规则“最小大小”为目标。

With your logic it's absolutely clear every competitor should produce the same result. 根据您的逻辑,绝对清楚每个竞争对手都应产生相同的结果。

The real world answer to this is for example: 现实世界对此的答案例如:

Hugi Size Coding Competition Series - Compo29 - Random Maze Builder Hugi尺寸编码比赛系列 -Compo29-随机迷宫生成器

12 entries, size of code (in bytes): 122, 122, 128, 135, 136, 137, 147, ... 278 (!). 12个条目,代码大小(以字节为单位):122、122、128、135、136、137、147,... 278(!)。

And I bet the first two entries, both having 122B are probably different enough (too lazy to actually check them). 我敢打赌,前两个条目都具有122B可能足够不同(太懒了,无法实际检查它们)。

Now producing valid machine code from high level programming language and by machine (compiler) is lot more complex task. 现在,从高级编程语言和由机器(编译器)产生有效的机器代码要复杂得多。 And compilers can't compete with humans in reasoning, most of the "how good code is produced by c++ compiler" stems from C++ language itself being defined quite close to machine code (easy to compile) and from brute CPU power allowing the compilers to work on thousands of variants for particular code path, searching for near-optimal solution mostly by brute force. 而且,编译器无法在推理上与人类竞争,大多数“ c ++编译器如何产生良好的代码”源于C ++语言本身的定义非常接近于机器代码(易于编译),并且源于残酷的CPU功能,使编译器能够针对特定的代码路径处理成千上万的变体,主要通过蛮力搜索接近最佳的解决方案。

Still the numerical "reasoning" behind the optimizers are state of art in their own way, getting to the point where human are still unreachable, but more like in their own way, just as humans can't achieve the efficiency of compilers within reasonable effort for full-sized app compilation. 优化器背后的数字“推理”仍然以他们自己的方式发展到了人类无法触及的地步,但更像是以他们自己的方式,就像人无法在合理的努力下实现编译器的效率一样用于完整的应用程序编译。

At this point reasoning about some debug code being different in few helper prologue/epilogue instructions... Even if you would find difference in optimized code, and the difference being "obvious" to human, it's still quite a feat the compiler can produce at least that, as compiler has to apply universal rules on specific code, without truly understanding the context of task. 在这一点上,一些调试代码在少数帮助序言/结尾说明中有所不同的原因...即使您发现优化代码有所不同,并且这种差异对人类来说是“显而易见的”,但编译器仍然可以在此方面壮大最不重要的是,因为编译器必须在特定代码上应用通用规则,而不真正了解任务的上下文。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 gcc版本4.6.3上C程序的汇编版本 - Assembly version of c program on gcc version 4.6.3 为什么GCC为几乎相同的C代码生成如此完全不同的程序集? - Why does GCC generate such radically different assembly for nearly the same C code? 为什么gcc对于用户和内核级代码会产生不同的汇编结果 - Why gcc produce different assembly result for user and kernel level code gcc汇编代码输出与预期不同 - gcc Assembly code output different than expected 理解简单C程序生成的汇编代码 - Understand the assembly code generated by a simple C program 当使用c代码动态数组时,不同版本的gcc输出不同 - different output with different version of gcc, when code dynamic array using c 在C程序(与gcc一起编译)中的汇编代码(为masm编写)…如何? - Assembly code (written for masm) in C program (compiled with gcc)… how? 为什么C和C ++版本的代码之间的CRC计算不同? - Why is the CRC calculation different between C and the C++ version of the code? 它在 GCC 源代码中的哪个位置编译为不同的汇编语言? - Where in the GCC source code does it compile to the different assembly languages? 为什么GCC和Clang的结果与以下代码不同? - Why results of GCC and Clang are different with following code?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM