Что делает NOPL в системе x86?

Какова функция NOPL на машине x86? Кажется, что ничего не делает, но почему это всегда в коде сборки?

NOP – однобайтная операция «ничего не делать», буквально «без операции». NOPW, NOPL и т. Д. Являются эквивалентными do-nothings, но берут слова и длинные байты.

например

 NOP // 1byte opcode NOP // 1byte opcode 

эквивалентно

 NOPW // 2byte opcode. 

Они очень удобны для заполнения вещей, поэтому последовательность кода начинается с определенной границы памяти, занимая несколько байтов пространства инструкций, но фактически ничего не делая.

Единственный эффект NOP на CPU – увеличить IP / EIP на 1. Эквиваленты NOPx будут делать это на 2, 4 и т. Д. …

Согласно блогу Джона Фремлина: Операнды NOP на AMD64 , nopw , nopl и т. Д. – это синтаксис gas , а не синтаксис AT & T.

Ниже приведены кодировки команд, генерируемые gas для разных nop ‘s из источника gas для команд длиной от 3 до 15 байтов. Обратите внимание, что некоторые из них такие же, как рекомендованные Intel nop формы (см. Ниже), но не все. В частности, в более длинном gas nop используется несколько (до 5) последовательных 0x66 операндов 0x66 в разных nop формах, тогда как рекомендуемые nop формы Intel никогда не используют более одного 0x66 операндов 0x66 в любой рекомендуемой nop .

nop из исходного кода для газа 2,30 (переформатировано для удобочитаемости):

 /* nopl (%[re]ax) */ static const unsigned char alt_3[] = {0x0f,0x1f,0x00}; /* nopl 0(%[re]ax) */ static const unsigned char alt_4[] = {0x0f,0x1f,0x40,0x00}; /* nopl 0(%[re]ax,%[re]ax,1) */ static const unsigned char alt_5[] = {0x0f,0x1f,0x44,0x00,0x00}; /* nopw 0(%[re]ax,%[re]ax,1) */ static const unsigned char alt_6[] = {0x66,0x0f,0x1f,0x44,0x00,0x00}; /* nopl 0L(%[re]ax) */ static const unsigned char alt_7[] = {0x0f,0x1f,0x80,0x00,0x00,0x00,0x00}; /* nopl 0L(%[re]ax,%[re]ax,1) */ static const unsigned char alt_8[] = {0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; /* nopw 0L(%[re]ax,%[re]ax,1) */ static const unsigned char alt_9[] = {0x66,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; /* nopw %cs:0L(%[re]ax,%[re]ax,1) */ static const unsigned char alt_10[] = {0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; static const unsigned char *const alt_patt[] = { f32_1, f32_2, alt_3, alt_4, alt_5, alt_6, alt_7, alt_8, alt_9, alt_10 }; 

Intel использует различный синтаксис, и для всех длин команд от 1 до 9 байтов доступно nop . Существует несколько разных nop , так как все nop длиной более двух байтов принимают 1 операнд. 0x90 nop ( 0x90 ) является синонимом xchg (e)ax,(e)ax .

Руководство по программированию Intel® 64 и IA-32, том 2 (2A, 2B и 2C): Справочник по набору инструкций, AZ, ГЛАВА 4: ИНСТРУКЦИЯ ПО УСТАНОВКЕ, MZ перечисляет рекомендуемые формы для разных инструкций:

 Table 4-12. Recommended Multi-Byte Sequence of NOP Instruction Length Assembly Byte Sequence 2 bytes 66 NOP 66 90H 3 bytes NOP DWORD ptr [EAX] 0F 1F 00H 4 bytes NOP DWORD ptr [EAX + 00H] 0F 1F 40 00H 5 bytes NOP DWORD ptr [EAX + EAX*1 + 00H] 0F 1F 44 00 00H 6 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00H] 66 0F 1F 44 00 00H 7 bytes NOP DWORD ptr [EAX + 00000000H] 0F 1F 80 00 00 00 00H 8 bytes NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H 9 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00000000H] 66 0F 1F 84 00 00 00 00 00H 

Поэтому в дополнение к этим рекомендациям Intel Intel, есть много других nop . Помимо выравнивания инструкции к определенной границе памяти, как отмечает Марк B в своем ответе, nop также очень полезны в самомодифицируемом коде, отладке и обратном проектировании.

Фактически, NOP будет использоваться в коде сборки, когда код должен быть исправлен.

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

Команда заполнения должна действовать так же, как и NOP, хотя она может занимать несколько байтов.

Причина, по которой мы вставляем более сложную инструкцию, например 66 90, вместо нескольких NOP, – это одна команда, как правило, выполняется быстрее, чем несколько NOP.

  • Как читать и писать регистры x86 флаги напрямую?
  • Почему вы не можете установить указатель инструкции напрямую?
  • Как реализовать atoi с помощью SIMD?
  • Почему EDX должен быть 0, прежде чем использовать инструкцию DIV?
  • Использование базового указателя в C ++ inline asm
  • Медленная инструкция jmp
  • Что будет использоваться для обмена данными между streamами, выполняются на одном ядре с HT?
  • В чем смысл MOV (% r11,% r12,1),% edx?
  • Сборка - JG / JNLE / JL / JNGE после CMP
  • Режимы адресации на языке сборки (IA-32 NASM)
  • Изменение целевых настроек процессора в Visual Studio 2010 Express
  • Interesting Posts

    Android Bitmap для Base64 String

    Macbook Mini-DVI to VGA Output Broken – причина?

    Предупреждение об ошибке «Захват сильно в этом блоке, вероятно, приведет к циклу сохранения» в коде с поддержкой ARC

    Материнская плата не включается, пока она не остановится на ~ 10 минут без питания, подключенного к сети

    Возможно ли иметь делегат в качестве параметра атрибута?

    Загрузка Picasso изображения, созданного внутри AsyncTask

    Могу ли я преобразовать значение строки C # в экранированный строковый литерал

    Для чего предназначен регистр «FS» / «GS»?

    ProcessInfo и RedirectStandardOutput

    Сохранить идентификаторы, добавленные ssh-add, чтобы они сохранялись

    Как реализована среда выполнения обработки исключений C ++?

    Windows 7 Aero тема "greyed out" – не найдено исправления

    Получить методы classа с использованием отражения

    THREE.JS: получить размер объекта относительно положения камеры и объекта на экране

    Безопасность Springboot не работает

    Давайте будем гением компьютера.