Ответ 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
.
Прошло некоторое время с тех пор, как я подробно описал работу ассемблера, так что, возможно, я ошибаюсь, по крайней мере, по одному счету здесь...