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

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

3 ответа

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

например

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

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

NOPW // 2byte opcode.

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

Единственное влияние NOP на процессор заключается в увеличении IP/EIP на 1. Эквиваленты NOPx будут делать это на 2, 4 и т. д.

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

Ниже приведены кодировки команд, сгенерированные gas для разных nop из gas источник для команд длиной от 3 до 15 байт. Обратите внимание, что некоторые из них совпадают с рекомендациями Intel nop формы (см. ниже), но не все. В частности, в дольше nop "s gas использует несколько (до 5) подряд 0x66 префиксы операндов в разных nop формы, тогда как Intel рекомендует nop формы никогда не используют более одного 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 использует другой синтаксис, и есть nop Доступно для всех команд длиной от 1 до 9 байтов. Есть несколько разных nop х, как все nop более двух байтов принимают 1 операнд. Один байт nop (0x90) является синонимом xchg (e)ax,(e)ax,

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

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

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

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

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

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

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

Другие вопросы по тегам