Programación en Lenguaje Ensamblador

-El Verdadero Lenguaje de las Máquinas-

Mas Máquina que Hombre

–Como programar en lenguaje máquina–

Un programador de Ensamblador que no sabe programar en lenguaje máquina es como un químico que desconoce la manipulación del átomo. También se ha dicho mucho que programar en lenguaje máquina es imposible. Sin embargo, luego de algunos meses de insultar lamers y ver dibujitos en paint, considero que ya están listos para comenzar a hacer tal proeza.


cuadro gris

No todos los campos se usan en todas las instrucciones. El único indispensable es el de OpCode. Todos los demás son opcionales.

Veamos un poco que significa cada campo:

Prefijos.- Existen prefijos que modifican las instrucciones. Algunos de ellos son los modificadores de ancho de operando/dirección (66h y 67h), los de repetición para funciones de manejo de cadenas y el temible prefijo REX del que se hablará en otra nota.

OpCode.- Este es el único obligatorio. Una instrucción puede medir desde un solo byte, como por ejemplo un NOP (90h) o hasta 16 bytes como en algunos saltos largos. El campo de OpCode por si solo puede medir entre 1 y 3 bytes.

ModR/M.- Este es un byte que especifica los operandos de la instrucción. Por lo general se pueden expresar las combinaciones de operandos mas usuales tan solo con este, pero a veces es necesario otro byte para direccionamientos mas complejos.

SIB.- Su nombre viene de Scalar Index Base. Es el complemento de ModR/M. Con este es posible hacer combinaciones de registros y desplazamientos que no era posible lograr en los antiguos modelos de 16 bits.

Desplazamiento.- Puede medir entre 1 y 4 bytes. Especifica una localidad de memoria que puede ser absoluta o relativa.

Valor Inmediato.- Semejante al anterior, pero este número se usa para representar un valor inmediato. Un valor inmediato es cuando uno de los operandos de la instrucción es una constante.

Definitivamente tengo que poner un link mas directo a los manuales de Intel.

Ahora a insultar.- Lo primero que han de preguntarse es que gana uno programando en lenguaje máquina. Bueno, ademas de hacer algo que no cualquiera puede hacer y el aumento de la autoestima a lo que esto conduce. Si conocen por ejemplo los bytes ModRM y SIB ya no tendrán dudas sobre que combinaciones son válidas. También es posible activar instrucciones de los procesadores mas recientes sin tener que esperar a que aparezca un compilador que las use. Aunque en mi experiencia personal es mas sencillo construir tu propio ensamblador que hacer programas completos en lenguaje máquina y el resultado es igual de eficiente. Otra gracia que tiene es que cuando las instrucciones cumplen ciertas reglas de alineación dentro de la memoria se ejecutan mucho mas rápido que si solo las aventaras así como van.

Por cierto, este diagrama solo es válido para lo que Intel llama “modo de compatibilidad” es decir que si su sistema Windows es de 64 bits. El formato de la instrucción cambia un poco. En ese formato conocido como “IA-32e”. En ese modo de operación es posible manejar memoria mas allá de la barrera de los 4 Gbytes de manera directa. Aunque la única diferencia entre lo que acabo de explicar y este modo, tan solo es el prefijo REX que va entre los prefijos y el OpCode.

Por último, y nada mas para que se sientan un poco como Neo de Matrix, intenten insertar en el código de siempre algunas instrucciones en lenguaje máquina.

Para insertar una instrucción en lenguaje máquina, hacemos lo mismo que cuando inicializamos una localidad de memoria. Por ejemplo. Supongamos que tenemos este código:

         mov    eax, 666h

Si mandamos desplegar el contenido del acumulador con una función o usamos un depurador de códigos, veremos que eax contiene el valor hexadecimal 666. Ahora, si modificaramos el código de esta forma:

         mov	eax, 666h
         db  	90h

no sucedería nada. Pues db 90h es la instrucción NOP, daría lo mismo si escribiéramos NOP en lugar de 90h. Estanstrucción aperentemente inutil se usa para alinear código y acelerar su ejecución dentro del CPU. Ahora hagamos algo mas visible:

              mov       eax, 666h
              db	90h
              db	33h,0c0h

Si ahora desplegamos el contenido de EAX, este mostrará CERO. Esto es porque 33h,0c0h es el código máquina de XOR EAX, EAX. Pone en cero el contenido de EAX y es mucho mas rápida y ocupa un tercio de la memoria que MOV EAX, 0. En realidad no es necesario poner cada instrucción en un renglón. Es posible poner todos los códigos máquina en uno solo o partirnos como queramos. Al final el Ensamblador va a juntarlos todos de manera lineal.

Bueno, ya me extendí mucho, en próximas notas veremos mas sobre el lenguaje máquina y de paso exploraremos un poco el modo de operación de 64 bits. Esperen un pequeño BOOM de notas, porque ya vienen las vacaciones y voy a tener mas tiempo libre para escribir estupideces. Y si se aburren, consiganse la segunda parte de los manuales de intel (Instruction Set Reference) y traten de desensamblar a mano el programa PEDEMO.EXE. Con solo un editor HEX, o si no se atreven, con el OllyDbg pero sin mirar las instrucciones. Si pueden hacer esto y además se divierten, definitivamente les va a gustar programar en Ensamblador.

abril 4, 2009 - Posted by | ensamblador, programación, Uncategorized | , , , , ,

No hay comentarios aún.

Deja un comentario