¿Por qué GCC emite "lea" en lugar de "sub" para la resta?
-
12-12-2019 - |
Pregunta
Estoy viendo un ensamblaje que se generó al desensamblar algunos programas en C y me confunde una única optimización que veo repetida con frecuencia.
Cuando no tengo optimizaciones en el compilador GCC usa el subl
instrucción para restar, pero cuando tengo las optimizaciones activadas (-O3
para ser precisos) el compilador utiliza un leal
instrucción en 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 una longitud de 3 bytes, por lo que no veo una optimización aquí.¿Alguien podría ayudarme e intentar explicar la elección del compilador?
Cualquier ayuda sería apreciada.
Solución
Es difícil saberlo 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
historias %edi - 1
en %ebp
. %edi
se conserva para uso futuro.
Otros consejos
Tenga en cuenta también que lea
no afecta a las banderas mientras que sub
hace.Entonces, si las instrucciones siguientes no dependen de que las banderas se actualicen mediante la resta, entonces no actualizar las banderas también será más eficiente.