Не секрет, что процессоры x86 (и x86_64) имеют не только однобайтную инструкцию NOP
, но и различные типы многобайтовых NOP-подобных инструкций.
Вот те, которые мне удалось найти:
Рекомендуем AMD, исх. Руководство по оптимизации программного обеспечения AMD для процессоров AMD Family 15h, документ # 47414, раздел 5.8 "Кодовое заполнение с переопределением операнда и многобайтовым NOP", страница 94)
90 NOP1_OVERRIDE_NOP
6690 NOP2_OVERRIDE_NOP
0f1f00 NOP3_OVERRIDE_NOP
0f1f4000 NOP4_OVERRIDE_NOP
0f1f440000 NOP5_OVERRIDE_NOP
660f1f440000 NOP6_OVERRIDE_NOP
0f1f8000000000 NOP7_OVERRIDE_NOP
0f1f840000000000 NOP8_OVERRIDE_NOP
660f1f840000000000 NOP9_OVERRIDE_NOP
66660f1f840000000000 NOP10_OVERRIDE_NOP
6666660f1f840000000000 NOP11_OVERRIDE_NOP
Рекомендован Intel, исх. Руководство разработчика программного обеспечения Intel 64 и IA-32 Volume 2B: Справочник по набору инструкций, N-Z, раздел "NOP"
90 NOP
6690 66 NOP
0f1f00 NOP DWORD ptr [EAX]
0f1f4000 NOP DWORD ptr [EAX + 00H]
0f1f440000 NOP DWORD ptr [EAX + EAX*1 + 00H]
660f1f440000 66 NOP DWORD ptr [EAX + EAX*1 + 00H]
0f1f8000000000 NOP DWORD ptr [EAX + 00000000H]
0f1f840000000000 NOP DWORD ptr [EAX + EAX*1 + 00000000H]
660f1f840000000000 66 NOP DWORD ptr [EAX + EAX*1 + 00000000H]
Ассемблер GNU (в binutils/gas) включает следующие шаблоны:
f32 (более старые Intel-совместимые процессоры до Pentium):
90 nop
6690 xchg %ax,%ax
8d7600 leal 0(%esi),%esi
8d742600 leal 0(%esi,1),%esi
908d742600 nop; leal 0(%esi,1),%esi
8db600000000 leal 0L(%esi),%esi
8db42600000000 leal 0L(%esi,1),%esi
908db42600000000 nop; leal 0L(%esi,1),%esi
89f68dbc2700000000 movl %esi,%esi; leal 0L(%edi,1),%edi
8d76008dbc2700000000 leal 0(%esi),%esi; leal 0L(%edi,1),%edi
8d7426008dbc2700000000 leal 0(%esi,1),%esi; leal 0L(%edi,1),%edi
8db6000000008dbf00000000 leal 0L(%esi),%esi; leal 0L(%edi),%edi
8db6000000008dbc2700000000 leal 0L(%esi),%esi; leal 0L(%edi,1),%edi
8db426000000008dbc2700000000 leal 0L(%esi,1),%esi; leal 0L(%edi,1),%edi
alt (для современных процессоров, то же самое для Intel и AMD):
0f1f00 nopl (%[re]ax)
0f1f4000 nopl 0(%[re]ax)
0f1f440000 nopl 0(%[re]ax,%[re]ax,1)
660f1f440000 nopw 0(%[re]ax,%[re]ax,1)
0f1f8000000000 nopl 0L(%[re]ax)
0f1f840000000000 nopl 0L(%[re]ax,%[re]ax,1)
660f1f840000000000 nopw 0L(%[re]ax,%[re]ax,1)
662e0f1f840000000000 nopw %cs:0L(%[re]ax,%[re]ax,1)
alt_short (для современных процессоров семейства AMD):
0f1f440000660f1f440000 nopl 0(%[re]ax,%[re]ax,1); nopw 0(%[re]ax,%[re]ax,1)
660f1f440000660f1f440000 nopw 0(%[re]ax,%[re]ax,1); nopw 0(%[re]ax,%[re]ax,1)
660f1f4400000f1f8000000000 nopw 0(%[re]ax,%[re]ax,1); nopl 0L(%[re]ax)
0f1f80000000000f1f8000000000 nopl 0L(%[re]ax); nopl 0L(%[re]ax)
0f1f80000000000f1f840000000000 nopl 0L(%[re]ax); nopl 0L(%[re]ax,%[re]ax,1)
alt_long (для современных процессоров семейства Intel):
66662e0f1f840000000000 data16; nopw %cs:0L(%[re]ax,%[re]ax,1)
6666662e0f1f840000000000 data16; data16; nopw %cs:0L(%[re]ax,%[re]ax,1)
666666662e0f1f840000000000 data16; data16; data16; nopw %cs:0L(%[re]ax,%[re]ax,1)
66666666662e0f1f840000000000 data16; data16; data16; data16; nopw %cs:0L(%[re]ax,%[re]ax,1)
6666666666662e0f1f840000000000 data16; data16; data16; data16; data16; nopw %cs:0L(%[re]ax,%[re]ax,1)
Мой вопрос заключается в следующем: существует ли распространенное/общее имя для всех этих байтовых последовательностей, таких как макросы, псевдомамоники или что-то в этом роде? До сих пор я обнаружил, что:
- AMD рекомендует называть их
NOPx_OVERRIDE_NOP
(x
= длина байта). - газ понимает
nopw
(как 2 байта nop) иnopl
(как 4 байта nop)
Как современные дизассемблеры имеют тенденцию выводить эти значения?
Связанный, но не повторяющийся вопрос: Что делает NOPL в системе x86?