0

Using this site, I generated assembly code for a simple program.

main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     DWORD PTR [rbp-4], 5
        mov     eax, DWORD PTR [rbp-4]
        mov     edi, eax
        mov     eax, 0
        call    ifunc
        mov     eax, 0
        leave
        ret

Here value of a is loaded from memory into eax and then it is moved to edi to pass to function. But I wrote a similar assembly code and directly loaded value of a into edi. Both works fine. Does GCC follows this for some kind of optimization? What is the benefit of loading eax first?

Sourav Kannantha B
  • 2,860
  • 1
  • 11
  • 35
  • 2
    Add `-O3` to the compiler options to see the optimized code. https://godbolt.org/z/WMEd4Y – Eugene Sh. Mar 10 '21 at 18:39
  • So, this is just unoptimized code and has nothing to do with some special behavior of either eax or edi? – Sourav Kannantha B Mar 10 '21 at 18:44
  • You could consult your assembler manual to see what instructions and addressing modes are valid.... – Martin James Mar 10 '21 at 18:59
  • @EugeneSh. Also add `extern void ifunc(int);` above main to get rid of that mysterious extra `xor eax, eax` before the call. (Without a prototype, `ifunc` is treated as variadic.) – zwol Mar 10 '21 at 19:00
  • @zwol Yep. Also have to explicitly mention `void` argument if function accepts no argument. – Sourav Kannantha B Mar 10 '21 at 19:04
  • @SouravKannanthaB Yes, in C `T fn()` isn't a prototype. – zwol Mar 10 '21 at 19:46
  • Near duplicate of [Return value in unused parameter when falling off the end of a non-void function](https://stackoverflow.com/q/57437831) - GCC `-O0` evaluates expressions in the return-value register. – Peter Cordes Sep 20 '21 at 14:14

1 Answers1

4

Does GCC follows this for some kind of optimization?

Just the opposite. You're compiling without optimizations so gcc doesn't do the optimization that would have removed the redundant movs and the unnecessary allocation of a as a variable in stack memory.

What is the benefit of loading eax first?

It has none and is just redundant. It is very common for unoptimized compiler code to contain stupid-looking stuff like this.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
  • GCC `-O0` likes to evaluate non-constant expressions in the return-value register (if it needs a register at all), even across other ISAs. It's common these days for CodeGolf.SE C answers to depend on that behaviour ([Tips for golfing in C](https://codegolf.stackexchange.com/a/106067)), which means they're actually written in `gcc -O0` language, not even trying to really be C, unfortunately. I mention this only because it's led to some more detailed discussion of the fact that GCC uses EAX this way. – Peter Cordes Mar 11 '21 at 00:47
  • Related: [Return value from writing an unused parameter when falling off the end of a non-void function](https://stackoverflow.com/q/57437831) - further discussion of GCC evaluating expressions into the return-value register, on any ISA I've looked at. (But mostly just pointing out that falling off the end of a non-`void` function after doing this only "works" because of that coincidence.) – Peter Cordes Jul 19 '23 at 19:52