Search code examples
gccassemblyx86compiler-optimizationgnu-assembler

Why does GCC emit "lea" instead of "sub" for subtraction?


I am looking at some assembly that was generated by disassembling some C programs and I am confused by a single optimization that I see repeated frequently.

When I have no optimizations on the GCC compiler uses the subl instruction for subtraction, but when I do have optimizations turned on (-O3 to be precise) the compiler uses a leal instruction instead of subtraction, example below:

without optimizations:

83 e8 01     subl $0x1, %eax 

with optimizations

8d 6f ff     leal -0x1(%edi), %ebp 

Both of these instructions are 3 bytes long, so I am not seeing an optimization here. Could someone help me out and try to explain the compiler's choice ?

Any help would be appreciated.


Solution

  • It's hard to tell without seeing the original C code that produces this.

    But if I had to guess, it's because the leal allows the subtraction to be done out-of-place without destroying the source register.

    This can save an extra register move.


    The first example:

    83 e8 01     subl $0x1, %eax 
    

    overwrites %eax thereby destroying the original value.

    The second example :

    8d 6f ff     leal -0x1(%edi), %ebp 
    

    stores %edi - 1 into %ebp. %edi is preserved for future use.