NOP

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску

В информатике NOP или NOOP (сокращение от английского: «No OPeration») инструкция процессора на языке ассемблера, или команда протокола, которая предписывает ничего не делать.

NOP как машинная инструкция

[править | править код]

Набор команд многих процессоров содержит инструкцию, цель которой состоит не в том, чтобы изменить состояние какого-либо регистра или ячейки памяти, а в том чтобы затратить определённое число тактов процессора. Для тех процессоров, в которых специальная инструкция отсутствует, NOP имитируется какой-то другой инструкцией с такими параметрами, что никакие действия не производятся (регистры и флаги не меняются). Например, в SPARC-процессорах в качестве NOP рекомендуется инструкция "sethi 0, %g0"). В архитектуре x86 команда NOP кодируется одним байтом 90h, в микропроцессоре Z80 — байтом 00h.

NOP’ы обычно используются:

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

Инструкция для x86-совместимых процессоров (фирм Intel, AMD и др.):

  • Обозначение (мнемоника): NOP
  • Количество используемых тактов: 3 (однако следует помнить, что в современных процессорах количество тактов однозначно не определяется)
  • Размер: 1 Байт
  • Код машинной команды (опкод): 0x90

На самом деле, инструкция NOP для x86-процессоров эквивалентна XCHG EAX,EAX (или XCHG AX,AX в реальном режиме), которая имеет тот же опкод 0x90 и не производит никакого эффекта, за исключением следующих специальных случаев:

  • Сочетание "REP NOP" (0xF3 0x90) в процессорах, начиная с Xeon и Pentium 4, интерпретируется как команда PAUSE, сообщая процессору, что программа выполняет цикл ожидания изменения другими процессорами состояния ячейки памяти, что позволяет процессору оптимизировать работу с памятью и энергопотребление.

Дорожка NOP’ов

[править | править код]

«Дорожка NOP’ов» или «трамплин NOP’ов» — известный хакерский приём, связанный с исполнением произвольного кода.

Наиболее распространённая причина исполнения произвольного кода — переполнение буфера. Впрочем, зачастую адрес, который запишется вместо точки возврата, известен лишь приблизительно. В таком случае создаётся такой код.

 
 nop
 nop
 ...
 nop
 nop
 ;тут вредоносный код

Перейдя на любой из NOP’ов, процессор в конце концов «скатится» на вредоносный участок.

«Длинные» варианты NOP

[править | править код]

Cуществуют различные варианты байтовых наборов, при исполнении которых процессор ничего не делает — «длинные» аналоги команды NOP. Простейший двухбайтовый вариант NOP в 32-разрядной архитектуре x86 — команда XCHG AX,AX с машинным кодом 6690h. От обычной (однобайтовой) команды NOP отличается префиксом изменения разрядности операнда. Например, в среде Delphi для выравнивания размеров процедур и функций по границам двойного слова используются инструкции NOP (1 байт 90h), MOV EAX,EAX (2 байта 89C0h) или LEA EAX,[EAX+0] (3 байта 8D4000h). Другие «длинные» варианты команды NOP (они далеко не единственно возможные), начиная с длины 3 байта, приведены ниже:

  • 3 Байта — 0F1F00h,
  • 4 байта — 0F1F4000h,
  • 5 байт — 0F1F440000h,
  • 6 байт — 660F1F440000h,
  • 7 байт — 0F1F8000000000h,
  • 8 байт — 0F1F84000000000h,
  • 9 байт — 660F1F840000000000h,
  • 10 байт — 662E0F1F840000000000h,
  • 11 байт — 66662E0F1F840000000000h,
  • 12 байт — 6666662E0F1F840000000000h,
  • 13 байт — 666666662E0F1F840000000000h,
  • 14 байт — 66666666662E0F1F840000000000h,
  • 15 байт — 6666666666662E0F1F840000000000h.

В качестве примеров команды размером 4 байта, которая ничего не делает, можно также привести команду LEA SI,[SI] (машинный код 67668D34h) или команду MOVSX AX,AX (машинный код 660FBFC0h).

NOP в командах протокола

[править | править код]
Скриншот программы Telnet клиента при проверке команд NOOP и NOP в одной из реализации SMTP-протокола.

Многие протоколы, например telnet, содержат NOP-команду, которую клиент может отправить, чтобы получить ответ от сервера без выполнения каких-либо других действий. Команда NOOP присутствует в следующих наиболее известных протоколах:

Возможные применения команде NOP:

  • Ответ на команду NOP может быть использован клиентом для определения доступности сервера по сети.
  • Сервер может быть запрограммирован автоматически отключаться, если клиент некоторое время не посылает данных. В таком случае периодически посылаемая команда NOP означает, что клиент ещё «жив» и соединение разрывать нельзя.