Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 703
Hunter McMillen Avatar asked Oct 02 '12 01:10

Hunter McMillen


People also ask

What is the purpose of LEA instruction?

The lea instruction places the address specified by its first operand into the register specified by its second operand. Note, the contents of the memory location are not loaded, only the effective address is computed and placed into the register.

What is the purpose of LEA instruction in 8086?

LEA − Used to load the address of operand into the provided register. LES − Used to load ES register and other provided register from the memory.

What is the difference between MOV and Lea?

The source must be from memory or a register, and the destination is a register. The lea instruction copies an “effective address” from one place to another. Unlike mov, which copies data at the address src to the destination, lea copies the value of src itself to the destination.

What is the addressing mode of Lea?

The LEA (Load Effective Address) instruction is a way of obtaining the address which arises from any of the Intel processor's memory addressing modes. it moves the contents of the designated memory location into the target register.


2 Answers

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.

like image 112
Mysticial Avatar answered Sep 24 '22 08:09

Mysticial


Keep in mind also that lea does not affect the flags whereas sub does. So if the ensuing instructions do not depend on the flags being updated by the subtraction then not updating the flags will be more efficient as well.

like image 29
DocMax Avatar answered Sep 22 '22 08:09

DocMax