Почему GCC выдает «lea» вместо «sub» при вычитании?
-
12-12-2019 - |
Вопрос
Я смотрю на некоторую сборку, созданную в результате дизассемблирования некоторых программ на языке C, и меня смущает одна оптимизация, которую я вижу часто повторяющейся.
Когда у меня нет оптимизации, компилятор GCC использует subl
инструкция по вычитанию, но когда у меня включена оптимизация(-O3
если быть точным) компилятор использует leal
инструкция вместо вычитания, пример ниже:
без оптимизации:
83 e8 01 subl $0x1, %eax
с оптимизацией
8d 6f ff leal -0x1(%edi), %ebp
Обе эти инструкции имеют длину 3 байта, поэтому я не вижу здесь оптимизации.Может ли кто-нибудь помочь мне и попытаться объяснить выбор компилятора?
Любая помощь будет оценена по достоинству.
Решение
Трудно сказать, не видя исходного кода C, который это создает.
Но если мне пришлось гадать, то это потому, что leal
позволяет выполнять вычитание неуместно, не разрушая исходный регистр.
Это может сэкономить дополнительное перемещение регистра.
Первый пример:
83 e8 01 subl $0x1, %eax
перезаписывает %eax
тем самым уничтожая первоначальную ценность.
Второй пример:
8d 6f ff leal -0x1(%edi), %ebp
магазины %edi - 1
в %ebp
. %edi
сохраняется для будущего использования.
Другие советы
Имейте в виду также, что lea
не влияет на флаги, тогда как sub
делает.Таким образом, если последующие инструкции не зависят от флагов, обновляемых вычитанием, тогда нет обновление флагов также будет более эффективным.