Подтвердить что ты не робот

Почему Visual Studio использует xchg ax, ax

Я смотрел через сумасшествие моей программы (потому что он разбился) и заметил много

xchg    ax, ax

Я искал его и обнаружил, что это по сути ноль, но почему визуальная студия делает xchg вместо noop?

Приложение представляет собой 64-битное приложение С#.NET3.5, скомпилированное visual studio

4b9b3361

Ответ 1

В x86 инструкция NOP XCHG AX, AX

2 мнемонические команды собираются в один и тот же двоичный код. (На самом деле, я полагаю, что ассемблер мог использовать любой xchg регистра с самим собой, но AX или EAX - это то, что обычно используется для NOP, насколько я знаю).

XCHG AX, AX имеет свойства изменения значений регистра и изменения флагов (hey - it a no op!).


Изменить (в ответ на комментарий Anon.):

Хорошо, теперь я помню, что для инструкции xchg есть несколько кодировок. Некоторые берут набор мод/г/м бит (как и многие инструкции архитектуры Intel x86), которые указывают источник и назначение. Эти кодировки занимают более одного байта. Также существует специальная кодировка, которая использует один байт и обменивает регистр общего назначения с (E)AX. Если указанный регистр также (E)AX, вы имеете однобайтную инструкцию NOP. вы также можете указать, что (E)AX обмениваться с самим собой, используя более крупный вариант инструкции xchg.

Я предполагаю, что MSVC использует версию с несколькими байтами xchg с (E)AX в качестве источника и адресата, когда он хочет пережевывать более одного байта без операции - он принимает такое же количество циклов, как и одиночный байт xchg, но использует больше места. При разборке вы не увидите краткий байт xchg, декодированный как NOP, даже если результат тот же.

В частности xchg eax, eax или NOP могут быть закодированы как коды операций 0x90 или 0x87 0xc0 в зависимости от того, хотите ли вы использовать до 1 или 2 байта. Диссассемблер Visual Studio (и, возможно, другие) расшифровывает код операции 0x90 как команду NOP и расшифровывает код операции 0x87 0xc0 как xchg eax, eax.

Прошло некоторое время с тех пор, как я подробно описал работу ассемблера, так что, возможно, я ошибаюсь, по крайней мере, по одному счету здесь...

Ответ 2

xchg ax,ax и nop на самом деле являются одной и той же инструкцией, они сопоставляются с одним и тем же кодом операции (0x90 iirc). Это прекрасно, xchg ax,ax - No-Op. Почему нужно тратить лишние коды кода операции с инструкциями, которые ничего не делают?

Сомнительно, почему вы видите, как печатаются мнемоники. Я думаю, это просто недостаток в вашей разборке, нет двоичной разницы.

Ответ 3

Собственно, xchg ax,ax - это то, как MS разбирает "66 90". 66 - это переопределение размера операнда, поэтому оно якобы работает на ax вместо eax. Тем не менее, CPU все еще выполняет его как nop. Префикс 66 используется здесь, чтобы сделать команду двумя байтами в размере, обычно для целей выравнивания.

Ответ 4

MSVC помещает NOP в скомпилированный код для отладочных сборников, как правило. Это позволяет редактировать и продолжать работу.

Ответ 5

Я не знаю, связано ли это с вопросом, но многие функции Windows начинаются с MOV EDI, EDI. Это также 2 байта NOP. Два байта NOP полезны для кода hotpatch, потому что вы можете безопасно заменить его коротким JMP.

Ссылка: http://blogs.msdn.com/b/oldnewthing/archive/2011/09/21/10214405.aspx