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

assembly, compiler-optimization, gcc, gnu-assembler, x86

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.

Problem

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.

Original source

Related problems