En la escuela, hemos estado usando un programa de arranque para ejecutar programas independientes sin un sistema operativo. He estado estudiando este programa y cuando está habilitado el modo protegido, se ejecuta un salto lejano ensamblando directamente el código de operación y los operandos como datos dentro del programa. Esto era para el ensamblador GNU:¿Alguien puede explicar este código de operación J86 JMP ensamblado directamente?
/* this code immediately follows the setting of the PE flag in CR0 */
.byte 0x66, 0xEA
.long TARGET_ADDRESS
.word 0x0010 /* descriptor #2, GDT, RPL=0 */
En primer lugar, ¿por qué uno quiere hacer esto (en lugar de la tecla de acceso de instrucciones)?
He estado mirando los manuales de Intel, pero todavía estoy un poco confundido por el código. Específicamente en el Volumen 2A, página 3-549, hay una tabla de códigos de operación. La entrada pertinente:
EA *cp* JMP ptr16:32 Inv. Valid Jump far, absolute, address given in operand
el código de operación real es obvia, pero el primer byte, 0x66, me tiene confundido. En referencia a la tabla en el manual de Intel, el cp aparentemente significa que seguirá un operando de 6 bytes. Y obviamente 6 bytes siguen en las siguientes dos líneas. 0x66 codifica un 'Prefijo de anulación de tamaño de operando'. ¿Qué tiene esto que ver con el CP en la tabla? Esperaba que hubiera algún valor hexadecimal para el CP, pero en su lugar existe este prefijo de anulación. ¿Puede alguien aclarar esto por mí?
Aquí es un vertedero de OD:
c022 **ea66 0000 0001 0010** ba52 03f2 c030
TARGET_ADDRESS se definió como 0x00010000.
También estoy un poco confundido por la importancia de los dos últimos bytes. Sin embargo, esa parece ser otra pregunta por completo. Se está haciendo bastante tarde, y he estado mirando el código y los manuales de Intel durante horas, así que espero haber aclarado mi punto.
¡Gracias por mirar!
La gente usa códigos de operación (en lugar de instrucciones) por 2 razones.La primera razón es cuando el ensamblador es "menos que adecuado" y no brinda soporte para las instrucciones que necesitan (esto es/era común cuando se agregan nuevas instrucciones y los ensambladores más antiguos no las admiten aún). La segunda razón es cuando el ensamblador admite las instrucciones que necesitan, pero el programador no sabe cómo convencer al ensamblador para que lo genere. Básicamente, son malas herramientas (incluidas herramientas antiguas, una sintaxis confusa y/o mala documentación) o programadores incorrectos. – Brendan
Nota: Mi comentario anterior es "en general" y se aplica a todos los ensambladores. No uso GAS, y no tengo idea de si es compatible con la instrucción de "salto de 32 bits en código de 16 bits" o no (o qué tan buena/mala es la documentación). – Brendan