2012-10-02 40 views
9

Estoy mirando un ensamblado que se generó al desmontar algunos programas C y estoy confundido por una única optimización que veo repetidamente.¿Por qué GCC emite "lea" en lugar de "sub" para restar?

cuando no tengo optimizaciones en el compilador GCC utiliza la instrucción subl para la sustracción, pero cuando tengo que optimizaciones encendido (-O3 para ser precisos) el compilador utiliza una instrucción en lugar de la sustracción leal, ejemplo siguiente:

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.

Respuesta

13

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 de origen.

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 

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

+0

No lo había considerado desde esta perspectiva porque la versión no optimizada solo usa valores inmediatos en las restas. Gracias, esto fue muy útil. –

10

Tenga en cuenta también que lea no afecta a las banderas mientras que sub lo hace. Entonces, si las siguientes instrucciones no dependen de los indicadores que se actualizan por la resta, entonces no, actualizar las banderas será más eficiente también.

+0

Si 'lea' no afecta las banderas, ¿cómo es equivalente a' sub'? ¿No debería afectar las banderas para tener el mismo efecto que 'sub'? – crisron

+1

@crisron no son equivalentes y sirven para diferentes propósitos. Si no quiere/necesita efectos secundarios, use lea, de lo contrario use sub –

Cuestiones relacionadas