Cosas extrañas que aprendí mientras escribía un emulador de x86
- Explica varios datos curiosos y rarezas aprendidos al escribir emuladores de x86 y amd64
- En Time Travel Debugging (TTD), se usa un emulador de CPU para registrar la ejecución de un proceso a nivel de instrucciones
- La primera versión de TTD se llamaba iDNA, estaba escrita en ensamblador, era rápida, pero difícil de mantener
- La segunda versión se escribió en C++ y mejoró la mantenibilidad
Trivia inútil sobre la codificación de x86
- El esquema de codificación de x86 permite codificar la misma instrucción de varias maneras
- La instrucción
int 3 puede codificarse como CD 03 o CC
- El registro
EAX se conoce como el "registro acumulador" y realmente tiene diferencias en la codificación
- El prefijo
REX permite acceder a un rango más amplio de registros en código de 64 bits
- Las instrucciones pueden tener una longitud de hasta 15 bytes, y si se supera ese límite se produce una excepción
- El prefijo de sobrescritura de dirección permite referenciar direcciones de 32 bits en modo de 64 bits
Propiedades extrañas de las banderas
- La instrucción
INC no actualiza la bandera de acarreo, a diferencia de la instrucción ADD
- Las instrucciones
CMPXCHG8B/CMPXCHG16B solo modifican la bandera de cero
- Las instrucciones de desplazamiento y rotación dejan la bandera de overflow en estado indefinido cuando la cantidad de desplazamiento es mayor que 1
Más sorpresas sobre las instrucciones de desplazamiento
shr ax, 10h desplaza el registro ax 16 bits y lo convierte en 0
shr eax, 20h desplaza el registro eax 32 bits, pero el valor no cambia
- La cantidad de desplazamiento se enmascara con
1FH
Sobrescritura de segmento
- Los segmentos todavía se usan en código de 32 y 64 bits, principalmente para almacenamiento local de hilo
- En Windows, se usan los registros
FS o GS para referenciar el TEB (Thread Execution Block)
- En procesos de 32 bits se usa
FS, y en procesos de 64 bits se usa GS
- En modo de 64 bits, el valor del registro de segmento no es importante
Sobrescritura de segmento: más trivia
- En modo de 32 bits, el valor real del registro de segmento referencia el descriptor de segmento
- En modo de 64 bits, la base está controlada por el MSR
- En WinDbg no se puede leer directamente el valor de segmento de un proceso de 64 bits
Conclusión
- Este artículo ofrece una lista aleatoria de trivia sobre x86
- Escribir un emulador ayuda a comprender en profundidad cómo funciona la CPU
- Se pueden consultar excelentes recursos en el sitio web de Agner Fog
Resumen de GN⁺
- Explica varios datos curiosos y rarezas aprendidos al escribir emuladores de x86 y amd64
- Escribir un emulador ayuda a comprender en profundidad cómo funciona la CPU
- Cubre varias curiosidades, como los distintos métodos de codificación de la instrucción
int 3, el prefijo REX y la sobrescritura de segmento
- Se pueden consultar más recursos en el sitio web de Agner Fog
1 comentarios
Opiniones en Hacker News
glibcusa el hecho no oficial de que en Intel el destino no se modificaTZCNT/LZCNTson formas deBSF/BSRcon el prefijoF3, que se ignora en procesadores antiguos. El mismo código puede comportarse distinto según la CPUREX/VEX/EVEX.RXBse ignoran cuando no se aplicanREX2codifique registrosr16-r31, pero noxmm16-xmm31EVEXtiene distintos diseños según variosopcodecr.yp.to