¿cuál es la función de NOPL en la máquina x86? Parece que no hace nada, pero ¿por qué siempre está en el código de ensamblaje?¿Qué hace NOPL en el sistema x86?
Respuesta
NOP
es una operación de un byte "no hacer nada", literalmente "sin operación". NOPW, NOPL, etc. son equivalentes a nada, pero toman bytes de palabra y de largo tamaño.
p. Ej.
NOP // 1byte opcode
NOP // 1byte opcode
es equivalente a hacer
NOPW // 2byte opcode.
Son muy útil para cosas de relleno fuera por lo que una secuencia de código comienza en un límite de memoria en particular, mediante la adopción de unos pocos bytes de espacio de instrucción, aún no en realidad haciendo cualquier cosa.
único efecto de NOP en la CPU es incrementar IP
/EIP
por 1. Los equivalentes NOPx lo harán por 2, 4, etc ...
nunca oído hablar de la operación y NOPW NOPL en el conjunto de instrucciones x86 de un .. ni aparecen en Intel Instruction Set Reference :) Quizás mezcles diferentes arquitecturas – Jack
@Jack huele como la sintaxis de AT & T – harold
@harold No sé ... gcc se queja si uso nopw/nopl en lugar de nop – Jack
Editar: referencias añaden a gas
gas
documentación y codificaciones para diferentes nop
formas:
Según John Fremlin's blog: Operands to NOP on AMD64, nopw
, nopl
etc. son gas
sintaxis, no AT & sintaxis T.
A continuación se muestran las codificaciones de instrucciones generadas por gas
para nop
diferentes desde gas
source para longitudes de instrucción de 3 a 15 bytes. Tenga en cuenta que algunos son iguales a los formularios recomendados por nop
de Intel (consulte a continuación), pero no todos. En particular, en el más largo nop
's gas
utiliza múltiples (hasta 5) consecutivos 0x66
prefijos de operando en diferentes formas nop
, mientras que Intel recomienda nop
formas nunca utilice más de un prefijo 0x66
operando en un solo nop
instrucciones recomendadas.
nop
codificaciones de gas
source (reformateado para mejorar la legibilidad):
/* nopl (%[re]ax) */
static const char alt_3[] = {0x0f,0x1f,0x00};
/* nopl 0(%[re]ax) */
static const char alt_4[] = {0x0f,0x1f,0x40,0x00};
/* nopl 0(%[re]ax,%[re]ax,1) */
static const char alt_5[] = {0x0f,0x1f,0x44,0x00,0x00};
/* nopw 0(%[re]ax,%[re]ax,1) */
static const char alt_6[] = {0x66,0x0f,0x1f,0x44,0x00,0x00};
/* nopl 0L(%[re]ax) */
static const char alt_7[] = {0x0f,0x1f,0x80,0x00,0x00,0x00,0x00};
/* nopl 0L(%[re]ax,%[re]ax,1) */
static const char alt_8[] = {0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00};
/* nopw 0L(%[re]ax,%[re]ax,1) */
static const char alt_9[] = {0x66,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00};
/* nopw %cs:0L(%[re]ax,%[re]ax,1) */
static const char alt_10[] = {0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00};
/* data16
nopw %cs:0L(%[re]ax,%[re]ax,1) */
static const char alt_long_11[] = {0x66,0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00};
/* data16
data16
nopw %cs:0L(%[re]ax,%[re]ax,1) */
static const char alt_long_12[] = {0x66,0x66,0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00};
/* data16
data16
data16
nopw %cs:0L(%[re]ax,%[re]ax,1) */
static const char alt_long_13[] = {0x66,0x66,0x66,0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00};
/* data16
data16
data16
data16
nopw %cs:0L(%[re]ax,%[re]ax,1) */
static const char alt_long_14[] = {0x66,0x66,0x66,0x66,0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00};
/* data16
data16
data16
data16
data16
nopw %cs:0L(%[re]ax,%[re]ax,1) */
static const char alt_long_15[] = {0x66,0x66,0x66,0x66,0x66,0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00};
/* nopl 0(%[re]ax,%[re]ax,1)
nopw 0(%[re]ax,%[re]ax,1) */
static const char alt_short_11[] = {0x0f,0x1f,0x44,0x00,0x00,0x66,0x0f,0x1f,0x44,0x00,0x00};
/* nopw 0(%[re]ax,%[re]ax,1)
nopw 0(%[re]ax,%[re]ax,1) */
static const char alt_short_12[] = {0x66,0x0f,0x1f,0x44,0x00,0x00,0x66,0x0f,0x1f,0x44,0x00,0x00};
/* nopw 0(%[re]ax,%[re]ax,1)
nopl 0L(%[re]ax) */
static const char alt_short_13[] = {0x66,0x0f,0x1f,0x44,0x00,0x00,0x0f,0x1f,0x80,0x00,0x00,0x00,0x00};
/* nopl 0L(%[re]ax)
nopl 0L(%[re]ax) */
static const char alt_short_14[] = {0x0f,0x1f,0x80,0x00,0x00,0x00,0x00,0x0f,0x1f,0x80,0x00,0x00,0x00,0x00};
/* nopl 0L(%[re]ax)
nopl 0L(%[re]ax,%[re]ax,1) */
static const char alt_short_15[] = {0x0f,0x1f,0x80,0x00,0x00,0x00,0x00,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00};
Intel utiliza una sintaxis diferente, y hay nop
's disponibles para todas las longitudes de instrucción de 1 a 9 bytes. Hay varios nop
diferentes, ya que todos los nop
tienen más de dos bytes y aceptan 1 operando. Un byte nop
(0x90
) es sinónimo de xchg (e)ax,(e)ax
.
Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2 (2A, 2B & 2C): Instruction Set Reference, A-Z, CHAPTER 4: INSTRUCTION SET REFERENCE, M-Z listas recomienda nop
formas para diferentes longitudes instrucciones:
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
Así que además de estos nop
's recomendados por Intel, hay muchas otras nop
' s también. Además de alinear una instrucción a un límite de memoria específica, como Marc B menciona en su respuesta, nop
's son también muy útiles en la auto-modificación del código, depuración y la ingeniería inversa.
en cuenta que en AMD64, 'nop' ya no es sinónimo de' xchg eax, eax'. 'nop' no pone a cero los 32 bits superiores de' eax', pero 'xchg eax, eax' sí lo hace. – fuz
En realidad, NOP será utilizado en el código de montaje cuando el código necesita ser parcheado.
Debido a que el tamaño de las nuevas instrucciones puede ser diferente al de las anteriores, se necesita relleno.
La instrucción de relleno debe actuar igual que NOP, aunque puede ocupar varios bytes.
La razón por la que insertamos una instrucción más compleja, como 66 90, en lugar de varios NOP, es una instrucción que generalmente se ejecuta más rápidamente que varios NOP.
- 1. ¿Qué son CLD y STD para el lenguaje de ensamblaje x86? ¿Qué hace DF?
- 2. Desarrollo de un sistema operativo para la arquitectura x86
- 3. ¿Qué es lo que realmente hace un sistema operativo?
- 4. ¿Qué hace el @sign?
- 5. ¿Es posible ejecutar el ensamblaje x86 en un sistema operativo x64?
- 6. ¿por qué necesitamos zone_highmem en x86?
- 7. ¿Qué significa "push ebp" en ensamblaje x86?
- 8. ¿Qué significan los corchetes en x86 asm?
- 9. ¿Qué hace esto en javascript?
- 10. ¿En qué dirección comienza a ejecutarse el x86?
- 11. ¿Cómo se hace la integración del sistema?
- 12. Desarrollar un sistema operativo que no sea x86
- 13. ¿Qué hace el método super()?
- 14. ¿Qué hace el método registerNatives()?
- 15. ¿Qué hace el || operador hacer?
- 16. ¿Qué hace el atributo xmlns?
- 17. ¿Qué hace% en JavaScript?
- 18. ¿Qué hace el proceso csrss.exe?
- 19. ¿Qué hace '@_' en Perl?
- 20. ¿Qué hace == en Ruby?
- 21. ¿Qué hace% {} en Ruby?
- 22. ¿Qué hace la secuencia de instrucciones de ensamblaje "rep stos" x86?
- 23. ¿Qué hace el modificador final en Dart?
- 24. ¿Qué hace el operador unario en numpy?
- 25. ¿Qué hace el predicado s() en Prolog?
- 26. C# ¿qué hace el operador == en detalle?
- 27. ¿Qué hace el operador "+ =" en Java?
- 28. ¿Qué hace 's' en el modo visual?
- 29. ¿Qué hace el símbolo "@" en Powershell?
- 30. ¿Qué hace el touch/untouch en xcode?
Usted pregunta "¿por qué siempre está en el código de ensamblado?" - normalmente no se encuentran muchos NOP en el código de ensamblado. ¿Algún código específico que estás viendo tiene muchos NOP? – ugoren
¡Hombre, desearía poder "sentir" lo que hace el código! –
http://stackoverflow.com/questions/6776385/what-is-faster-jmp-or-string-of-nops/6777644 –