Por que o GCC emite “lea” em vez de “sub” para subtração?
-
12-12-2019 - |
Pergunta
Estou olhando para uma montagem que foi gerada pela desmontagem de alguns programas C e estou confuso com uma única otimização que vejo repetida com frequência.
Quando não tenho otimizações no compilador GCC uso o subl
instrução para subtração, mas quando tenho as otimizações ativadas (-O3
para ser mais preciso) o compilador usa um leal
instrução em vez de subtração, exemplo abaixo:
sem otimizações:
83 e8 01 subl $0x1, %eax
com otimizações
8d 6f ff leal -0x1(%edi), %ebp
Ambas as instruções têm 3 bytes, então não estou vendo uma otimização aqui.Alguém poderia me ajudar e tentar explicar a escolha do compilador?
Qualquer ajuda seria apreciada.
Solução
É difícil dizer sem ver o código C original que produz isso.
Mas se eu tivesse que adivinhar, é porque o leal
permite que a subtração seja feita fora do lugar sem destruir o registro fonte.
Isso pode economizar uma movimentação extra de registro.
O primeiro exemplo:
83 e8 01 subl $0x1, %eax
substitui %eax
destruindo assim o valor original.
O segundo exemplo:
8d 6f ff leal -0x1(%edi), %ebp
lojas %edi - 1
em %ebp
. %edi
é preservado para uso futuro.
Outras dicas
Tenha em mente também que lea
não afeta as bandeiras enquanto sub
faz.Portanto, se as instruções seguintes não dependem da atualização dos sinalizadores pela subtração, então não atualizar os sinalizadores também será mais eficiente.