Lange Multibyte-NOPs: allgemein verständliche Makros oder andere Notationen
Es ist kein großes Geheimnis, dass x86- (und x86_64-) Prozessoren nicht nur das Einzelbyte habenNOP
Befehl, sondern auch verschiedene Arten von Multi-Byte-NOP-ähnlichen Befehlen.
Es gibt die, die ich gefunden habe:
Empfohlen von AMD, ref.AMD Software Optimization Guide für 15h-Prozessoren der AMD-Familie, Dokument Nr. 47414, Abschnitt 5.8 "Codeauffüllung mit Operandengrößenüberschreibung und Multibyte-NOP", Seite 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
Empfohlen von Intel, ref.Intel 64- und IA-32-Architekturen Software-Entwicklerhandbuch Band 2B: Befehlssatzreferenz, N-ZAbschnitt "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 Assembler (in binutils / gas)enthält die folgenden Muster:
f32 (ältere Intel-kompatible CPUs bis 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 (für moderne CPUs gleich für 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 (für moderne CPUs der AMD-Familie):
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 (für moderne CPUs der Intel-Familie):
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)
Meine Frage ist folgende: Gibt es eine weit verbreitete / gemeinsame Benennung für all diese Bytefolgen, wie Makros, Pseudo-Mnemonics oder ähnliches? Bisher habe ich nur folgendes gefunden:
AMD empfiehlt, sie zu benennenNOPx_OVERRIDE_NOP
(x
= Bytelänge).Gas verstehtnopw
(als 2 Byte nop) undnopl
(als 4-Byte-NOP)Wie neigen moderne Disassembler dazu, diese Werte auszugeben?
Verwandte, aber nicht doppelte Frage:Was macht NOPL im x86-System?