简体   繁体   中英

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

I'm understanding the basics of assembly and c programming.

I compiled following simple program in 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

The disassembled code for above program with gcc version 4.4.7 is:

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:

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?
What is significance of 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. So, different compilers may generate different assembly code.

For your code, GCC 6.2 with -O3 generates just:

xor     eax, eax
ret

because your code essentially does nothing. So, it's reduced to a simple return statement.

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

12 entries, size of code (in bytes): 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).

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM