Какова цель кода операции NOP? - PullRequest
79 голосов
/ 24 октября 2008

Я прохожу MSIL и замечаю, что есть много nop инструкций. В статье MSDN говорится, что они не предпринимают никаких действий и используются для заполнения пространства, если исправлен код операции. Они используются гораздо чаще в отладочных сборках, чем в сборках релизов. Я знаю, что такого рода операторы используются на языках ассемблера, чтобы убедиться, что код операции помещается на границе слова, но зачем это нужно в MSIL?

Ответы [ 19 ]

98 голосов
/ 24 октября 2008

NOP служат нескольким целям:

  • Они позволяют отладчику размещать точку останова на строке, даже если она объединена с другими в сгенерированном коде.
  • Позволяет загрузчику выполнить прыжок с целевым смещением другого размера.
  • Позволяет выравнивать блок кода на определенной границе, что может быть полезно для кэширования.
  • Это позволяет инкрементное связывание для перезаписи кусков кода с помощью вызова нового раздела, не беспокоясь об общем размере изменения функции.
9 голосов
/ 25 октября 2008

Вот как nops используются при отладке:

Nops используются компиляторами языка (C #, VB и т. Д.) Для определения неявных точек последовательности. Они сообщают компилятору JIT, где обеспечить соответствие машинных инструкций инструкциям IL.

Запись в блоге Рика Байера на DebuggingModes.IgnoreSymbolStoreSequencePoints , объясняет некоторые детали.

C # также помещает Nops после инструкций вызова, так что местом возврата сайта в источнике является вызов, а не строка после вызова.

8 голосов
/ 24 октября 2008

Предоставляет возможность для строковых маркеров (например, точек останова) в коде, когда сборка выпуска не будет генерировать ни одного.

6 голосов
/ 25 октября 2008

Может также ускорить выполнение кода при оптимизации под конкретные процессоры или архитектуры:

Процессоры в течение длительного времени используют несколько конвейеров, которые работают примерно параллельно, поэтому две независимые команды могут быть выполнены одновременно. На простом процессоре с двумя конвейерами первый может поддерживать все инструкции, тогда как второй поддерживает только подмножество. Кроме того, между конвейерами существуют некоторые задержки, когда приходится ждать результата предыдущей инструкции, которая еще не закончена.

При этих обстоятельствах выделенный nop может принудительно ввести следующую инструкцию в конкретный конвейер (первый или не первый) и улучшить сопряжение следующих инструкций, чтобы стоимость Нет больше, чем амортизируется.

4 голосов
/ 24 октября 2008

Чувак! No-op это круто! Это инструкция, которая ничего не делает, но потребляет время. В неяркие темные времена вы могли бы использовать его для микрорегулировки времени в критических циклах или, что более важно, в качестве наполнителя в самомодифицирующемся коде.

3 голосов
/ 24 октября 2008

Они могут использовать их для поддержки редактирования и продолжения во время отладки. Он предоставляет отладчику пространство для работы для замены старого кода новым без изменения смещений и т. Д.

3 голосов
/ 28 мая 2009

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

загрузить значение для регистрации (занимает 8 циклов) № 8 добавить 1 для регистрации

Это удостоверило, что регистр имел правильное значение перед операцией добавления.

Другое использование заключалось в заполнении исполнительных блоков, таких как векторы прерываний, которые должны были быть определенного размера (32 байта), потому что адрес для вектора 0 был, скажем, 0, для вектора 1 0x20 и так далее, поэтому компилятор установил NOP там, если нужно.

3 голосов
/ 25 октября 2008

Nop необходим в полезной нагрузке эксплойтов переполнения буфера.

3 голосов
/ 28 мая 2009

50 лет слишком поздно, но эй.

Nop полезны, если вы набираете код сборки вручную. Если вам нужно было удалить код, вы можете удалить старые коды операций.

похоже, вы можете вставить новый код, переписав какой-либо код операции, и перейти в другое место. Там вы помещаете перезаписанные коды операций и вставляете новый код. Когда будешь готов, ты прыгнешь назад.

Иногда вам приходилось использовать доступные инструменты. В некоторых случаях это был просто очень простой редактор машинного кода.

В настоящее время с компиляторами техники больше не имеют никакого смысла.

3 голосов
/ 25 октября 2008

Как сказал ddaa, nops позволяет учесть отклонения в стеке, поэтому при перезаписи адреса возврата он переходит на салазки nop (много nops в строке), а затем корректно выполняет исполняемый код, а не прыжок на некоторый байт в инструкции, которая не является началом.

...