gcc assembly x86 compiler-optimization gas

¿Por qué GCC emite "lea" en lugar de "sub" para la resta?



assembly x86 (2)

Es difícil de decir sin ver el código C original que produce esto.

Pero si tuviera que adivinar, es porque el leal permite que la resta se realice fuera de lugar sin destruir el registro fuente.

Esto puede ahorrar un movimiento de registro adicional.

El primer ejemplo:

83 e8 01 subl $0x1, %eax

sobrescribe %eax destruyendo así el valor original.

El segundo ejemplo:

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

almacena %edi - 1 en %ebp . %edi se conserva para uso futuro.

Estoy mirando un ensamblado que se generó al desmontar algunos programas C y estoy confundido por una optimización única que veo repetida frecuentemente.

Cuando no tengo optimizaciones en el compilador de GCC, subl instrucción subl para la resta, pero cuando tengo activadas las optimizaciones ( -O3 para ser precisos) el compilador usa una instrucción leal lugar de resta, ejemplo a continuación:

sin optimizaciones:

83 e8 01 subl $0x1, %eax

con optimizaciones

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

Ambas instrucciones tienen 3 bytes de longitud, por lo que no veo una optimización aquí. ¿Podría alguien ayudarme y tratar de explicar la elección del compilador?

Cualquier ayuda sería apreciada.


Tenga en cuenta también que lea no afecta a las banderas mientras que sub hace. Entonces, si las instrucciones subsiguientes no dependen de que las banderas se actualicen mediante la resta, entonces no actualizar las banderas será más eficiente también.