Pregunta:
¿El desmontaje muestra "LEA" con RIP?
Evan Carroll
2018-04-16 09:49:48 UTC
view on stackexchange narkive permalink

Cuando desmonto esta instrucción usando pad en Radare, obtengo un LEA con rip

  [0x00000000] > pad 8d 15 c8 90 04 08lea edx, [rip + 0x80490c8]  

Recibí esta instrucción de esta publicación aquí Sin embargo, estoy confundido ¿por qué el desmontaje muestra rip + 0x80490c8 , cuando la publicación original afirma que es el equivalente de mov ? ¿Es esta la salida desmontada correcta? ¿Por qué estaría el puntero de instrucción en LEA ? ¿Es eso una base implícita o el póster original cometió un error?

Dos respuestas:
#1
+8
Megabeets
2018-04-16 09:57:40 UTC
view on stackexchange narkive permalink

Es simplemente una cuestión de bits. En el ejemplo que se muestra, los pares hexagonales se desmontan utilizando un ensamblaje de 64 bits y probablemente desee cambiarlo a un ensamblaje de 32 bits. Solo dile a radare que estás trabajando con 32 bits y hará el trabajo por ti:

  [0x00000000] > pad 8d 15 c8 90 04 08lea edx, [rip + 0x80490c8] [0x00000000] > e asm.bits = 32 [0x00000000] > pad 8d 15 c8 90 04 08lea edx, [0x80490c8]  

A diferencia de las instrucciones de los modos de 32 bits que se tomaron como direcciones absolutas (use el desplazamiento inmediato de 32 bits direccionamiento), los modos de 64 bits (también conocidos como modo largo) suelen utilizar un desplazamiento de 32 bits del RIP actual, no de 0x00000000 como antes. Eso significa que no tiene que saber la dirección absoluta de algo que desea hacer referencia, solo necesita saber qué tan lejos está de la instrucción que se está ejecutando actualmente.

Hay muy pocos modos de direccionamiento que utilicen una dirección absoluta completa de 64 bits. La mayoría de los modos de direccionamiento son compensaciones de 32 bits en relación con uno de los registros de 64 bits (generalmente RIP).

eso es interesante. Pude ver que sucedía al revés, pero me pregunto cómo se tradujo el código de operación de 32 bits al mismo código de operación de 64 bits con el operando RIP (gratis).
Se agregó una explicación de la razón detrás. Nuevamente, simplemente el cambio de 32 bits a 64 bits
@EvanCarroll: si ha estado haciendo esto durante el tiempo suficiente para estar familiarizado con él, es similar a la forma en que al pasar del código de 16 bits a 32 bits se cambiaron todas sus referencias de 'ax' (etc.) a 'eax': en cada modo hay configuraciones predeterminadas que están diseñadas para ser sensibles * para ese modo *, que provocan ligeros cambios en la interpretación de cada instrucción.
@EvanCarroll: x86 de 32 bits tiene 2 formas redundantes de codificar `[disp32]` (sin registros): con y sin SIB. x86-64 reutilizó la versión sin SIB para que signifique "[RIP + rel32]", dejando que la versión más larga con-SIB todavía signifique "[sign_extended_disp32]" como cuando usa un disp32 con registros GP. En la sintaxis NASM, `[rel foo]` frente a `[abs foo]`, o use `default rel`.
@Megabeets: Sólo la forma especial `mov al / ax / eax / rax, moffs` de` mov` (y la forma de almacenamiento) usan una dirección absoluta completa de 64 bits / 8 bytes. No hay modos de direccionamiento ModR / M que se puedan usar con otras instrucciones que acepten más de un disp32 absoluto. Entonces, su última oración podría decir que no hay modos de direccionamiento normales. De hecho, eso es un poco extraño. * normalmente *, solo usa pequeñas compensaciones relativas a una dirección en los registros, como `[rdi + 8]`, * o * RIP-relativo. Pero sí, en el código dependiente de la posición, puede indexar una matriz estática con `[matriz + rdi]`.
#2
+3
Peter Cordes
2018-04-17 10:09:21 UTC
view on stackexchange narkive permalink

El x86 de 32 bits tiene 2 formas redundantes de codificar [disp32] (sin registros): con y sin un byte SIB. Los ensambladores, por supuesto, siempre usarán la forma más corta, y eso es lo que muestra el enlace en su pregunta.

Está desensamblando como código de máquina de 64 bits.

x86-64 reutilizado la versión sin-SIB significa [RIP + rel32] , dejando que la versión más larga con-SIB todavía signifique [sign_extended_disp32] como cuando usa un disp32 con registros GP. (El relativo a RIP no está disponible combinado con ningún registro GP; solo esta codificación ModR / M específica).

En la sintaxis NASM, [rel foo] vs. [abs foo] , o use default rel .


AFAIK, lea r32, [disp32] en lugar de mov r32, imm32 nunca es útil para el rendimiento en ninguna CPU que conozca, excepto para hacer una instrucción más larga a propósito en lugar de rellenar con NOP.

El único caso de uso de lea para direcciones estáticas es en código de 64 bits con LEA relativo a RIP.

Consulte esta respuesta canónica para obtener más información. sobre LEA, pero en realidad esta pregunta no tiene nada que ver con LEA específicamente, y habría ocurrido con cualquier instrucción que usara un modo de direccionamiento disp32 ModR / M decodificado en el modo incorrecto. Solo se encontró con esto porque encontró un ejemplo que comparaba el uso de un lea ineficiente con un mov eficiente -inmediato en modo de 32 bits.



Esta pregunta y respuesta fue traducida automáticamente del idioma inglés.El contenido original está disponible en stackexchange, a quien agradecemos la licencia cc by-sa 3.0 bajo la que se distribuye.
Loading...