В чем смысл LEA EAX, [EAX]?

LEA EAX, [EAX]

Я столкнулся с этой инструкцией в бинарном файле, скомпилированном с помощью компилятора Microsoft C. Он явно не может изменить значение EAX. Тогда почему оно там?


person Frederick The Fool    schedule 24.04.2010    source источник
comment
@Potatoswatter: Да, это релизная версия бинарника, поэтому оптимизация должна быть включена. Кроме того, я использую ollydbg для дизассемблирования.   -  person Frederick The Fool    schedule 24.04.2010
comment
У вас есть соответствующий оператор C для этого драгоценного камня?   -  person Wikser    schedule 24.04.2010
comment
@Wikser: Нет. И это не единичный случай. Я видел один или два других, таких как LEA EBX, [EBX] в том же бинарном файле. На самом деле, я смотрю на последний прямо сейчас на моем экране. Ollydbg показывает код операции для этого (LEA EBX, то есть [EBX]) как 8D9B 00000000.   -  person Frederick The Fool    schedule 24.04.2010
comment
Если это 64-битный двоичный файл, то это просто ноль из старших 32 бит.   -  person phuclv    schedule 31.10.2013


Ответы (3)


It is a NOP.

Следующие обычно используются как NOP. Все они делают одно и то же, но машинный код получается разной длины. В зависимости от требований к центровке выбирается один из них:

xchg eax, eax         = 90
mov eax, eax          = 89 C0 
lea eax, [eax + 0x00] = 8D 40 00 
person codaddict    schedule 24.04.2010
comment
На самом деле это не совсем NOP, поскольку вводит зависимость данных от EAX. Современные ЦП определяют этот конкретный шаблон как NOP и игнорируют зависимость данных, но некоторые старые ЦП могут этого не делать. - person Jörg W Mittag; 24.04.2010
comment
На самом деле код операции для nop — это 0x90, который совпадает с xchg eax, eax. - person Nathan Fellman; 24.04.2010
comment
Ну, это неправильно, что современные процессоры определяют этот конкретный шаблон как NOP, они все еще вводят false цепочки зависимостей данных. Есть только некоторые настоящие NOP, где декодеры просто не вводят никаких зависимостей от данных. - person Quonux; 15.07.2010
comment
@Quonux, многобайтовые NOP давно стали официальными. . В этом ответе также перечислены официальные NOP от Intel размером от 2 до 9 байт. - person phuclv; 24.06.2014

Из этой статьи:

Этот прием используется компилятором MSVC++ для выдачи инструкций NOP разной длины (для заполнения перед целями перехода). Например, MSVC++ генерирует следующий код, если ему требуется 4-байтовое и 6-байтовое заполнение:

8d6424 00 lea [ebx+00],ebx ; 4-байтовое заполнение 8d9b 00000000
lea [esp+00000000],esp ; 6-байтовое заполнение

Первая строка помечена как «npad 4» в ассемблерных листингах, сгенерированных компилятором, а вторая — «npad 6». Регистры (ebx, esp) можно выбирать из редко используемых, чтобы избежать ложных зависимостей в коде.

Так что это просто своего рода NOP, появляющийся прямо перед целями инструкций jmp для их выравнивания.

Интересно, что вы можете определить компилятор по характерному характеру таких инструкций.

person Frederick The Fool    schedule 24.04.2010
comment
Сказать, что это NOP, — это только половина ответа (но, как ни странно, выбранный). Объяснение, почему вы хотите сделать эти NOP, является полным ответом. Отличная работа. - person JUST MY correct OPINION; 24.04.2010
comment
Я столкнулся с этим и с помощью компилятора MSVC++. - person Jeroen Baert; 14.08.2015

LEA EAX, [EAX]

Действительно, не изменяет значение EAX. Насколько я понимаю, по функциям он идентичен:

MOV EAX, EAX

Вы видели это в оптимизированном коде или в неоптимизированном коде?

person Eli Bendersky    schedule 24.04.2010
comment
Хорошо оптимизированный код. Но как это оправдывает/объясняет LEA? - person Frederick The Fool; 24.04.2010
comment
@Frederick: если бы он не был оптимизирован, я думаю, было бы разумно, если бы компилятор использовал LEA для каких-то вычислений, а особый случай сгенерировал этот избыточный оператор (это происходит в неоптимизированном коде) - person Eli Bendersky; 24.04.2010
comment
Это двоичный файл, выпущенный для клиентов моей компанией. Так что это должна быть оптимизированная версия. - person Frederick The Fool; 24.04.2010
comment
Так что это должна быть оптимизированная версия. Не обязательно. Что, если они забыли включить /O2? - person Alex Budovski; 24.04.2010
comment
инструкция LEA может выполняться быстрее на Pentium 4, чем инструкция MOV (и вычисления по-прежнему выполняются быстро с использованием LEA), поэтому я бы назвал это причиной для LEA. - person Quonux; 15.07.2010