1

i have this c code:

#include <stdio.h>
    int main()
    {
        int x = 10;
        int y = 20;
        int z =  30;
        return 0;
    }

when i compile it using gcc v4.8.5 & disassemble it using gdb it gives

   0x00000000004004f3 <+0>:     push   %rbp
   0x00000000004004f4 <+1>:     mov    %rsp,%rbp
   0x00000000004004f7 <+4>:     movl   $0xa,-0xc(%rbp)
   0x00000000004004fe <+11>:    movl   $0x14,-0x8(%rbp)
   0x0000000000400505 <+18>:    movl   $0x1e,-0x4(%rbp)
   0x000000000040050c <+25>:    mov    $0x0,%eax
   0x0000000000400511 <+30>:    pop    %rbp
   0x0000000000400512 <+31>:    retq   

But when i disassemble it using godbolt(here) i get this output.

main:
  pushq %rbp
  movq %rsp, %rbp
  movl $10, -4(%rbp) //---> offset for value 10 was 12 bytes from $rbp in the above version but here it is 4 bytes ?
  movl $20, -8(%rbp)
  movl $30, -12(%rbp)
  movl $0, %eax
  popq %rbp
  ret

in both the outputs, there is the difference in the offset from $rbp. addresses for variables in Godbolt assembly seems reversed. why is it so?is it just a compiler thing & machine dependent?

JFMR
  • 23,265
  • 4
  • 52
  • 76
anekix
  • 2,393
  • 2
  • 30
  • 57
  • 2
    I'm not even sure if there's guaranteed stability between two runs of compiler, certainly from the godbolt gcc outputs it looks so (i.e. the same version with same options with same source will produce same machine code), but you have to have some guarantee from the compiler vendor to expect that (never bothered to read enough of gcc docs to confirm it should be stable on several runs). Your question is sort of weird, why do you expect it to be same? – Ped7g Feb 23 '18 at 09:03
  • @Ped7g i do not expect it to be same. i just wanted to know whether its compiler dependent ? – anekix Feb 23 '18 at 09:07
  • 4
    As opposed to structure members, variable declaration order is left to the compiler (for instance to pack/align similar data or whatever its internals dictate) So both outputs are perfectly expectable. there's a good question I linked to as duplicate. – Jean-François Fabre Feb 23 '18 at 09:07
  • 2
    BTW, if you will use `-O3`, you will get probably something as `xor eax,eax` `ret`, which is sort of optimal, and it would be rare to find compiler with different machine code for such trivial function, but if you would try to compile some more complex function with some actual meaningful code, then every compiler will produce somewhat different machine code, as it is both costly to find "optimal" solution, so no compiler runs long enough to find it, and also it is almost in every case impossible to define what is "optimal" (you can optimize for size of resulting code, for performance, etc) – Ped7g Feb 23 '18 at 09:08
  • 1
    @anekix no, it's hardly stable for multiple runs over the same source (in the same environment with the same compiler and of course the same options). For trivial sources the output will be probably deterministic and stable, for complex sources it depends on the gcc version, this old article may give you idea how fragile that is: http://blog.mindfab.net/2013/12/on-way-to-deterministic-binariy-gcc.html – Ped7g Feb 23 '18 at 09:13
  • 1
    and this one (link from the article) is relevant too: https://stackoverflow.com/questions/14653874/how-to-produce-deterministic-binary-output-with-g (but unless you are pursuing stable builds for some particular reason, you probably don't need to delve so deep into it, just accept the machine code output is sort of random (even between multiple identical compilation runs) - unless there's something guaranteed by the language itself (C datatypes and structures are quite well defined, together with specified packing/alignment options you can get (almost?) bit precision), or the compiler vendor. – Ped7g Feb 23 '18 at 09:20
  • And last comment (hopefully :) ) .... The C doesn't even define where the local variables will land, the compiler may have as well decided, that `x` will be kept in `rdi`, and just do `mov edi, 10`, not having it at stack at all. And that's what it would very likely do with optimizations enabled, if it would need `x` at all and would have some spare register to keep it "hot" in the CPU during whole function implementation. – Ped7g Feb 23 '18 at 09:25
  • Are the differences only because you use different disassemblers or do you use also different compilers? This is not clear from your question. – Uwe Plonus Feb 23 '18 at 10:20
  • @Ped7g: The same gcc binary will produce the same instructions from the same source every time. Different versions of gcc can of course be different, or even different builds of the same version (especially if any config options differ). The article you linked only describes metadata and randomized symbol names varying from run to run, not any code-gen choices. – Peter Cordes Feb 23 '18 at 18:17
  • @PeterCordes I had that suspicion, but 3min google search for gcc docs with such warranty were not successful, and there's nothing obvious about that, quite contrary, I can easily imagine compiler not doing that (although it must be then very painful to debug such compiler). – Ped7g Feb 23 '18 at 20:39

0 Answers0