Programación en Lenguaje Ensamblador

-El Verdadero Lenguaje de las Máquinas-

Revancha de 32 Bits

–Y el Retorno de los Programadores de Ensamblador–

Esta es la cuarta y última parte de la Saga de 32 Bits. Donde se muestra como luego de ser desterrados por los lamers, los programadores de Ensamblador regresamos a reclamar nuestro lugar en los PC’s actuales basadas en Windows con CPU de Intel. Aunque algunos parece que aún no se han dado cuenta y en pleno siglo XXI siguen programando para los procesadores de 16 bits como el 8086.

peheader

Luego de escribir las tres notas anteriores revisé una vieja bitácora que comencé a escribir mas o menos por el otoño del 2000. Encontré una referencia de la primavera del 2004 en la que se menciona un primer intento por programar en ensamblador para Windows. Lo interesante de esta primera aproximación fue que en lugar de comenzar a programar como con cualquier otro lenguaje. Buscando tutoriales, libros y hablando con ‘profesionales de la industria’ lo que hicimos fue irnos directo contra el formato binario de los archivos ejecutables. Ya teníamos algo de experiencia estudiando código ejecutable de tiempos del DOS con sus famosos archivos de formato MZ. No puedo describirles la sensación que uno tiene cuando por primera vez abre un programa ejecutable en un editor hexadecimal y entiende lo que significan cada uno de esos números. Y mas aún cuando puedes manipular un archivo binario sin mas herramienta que un editor hexadecimal y ver como la aplicación cambia su conducta. En el caso del Windows este formato era conocido como PE (Portable Executable) y hasta tiene un encabezado compatible con MS-DOS que despliega un mensaje que dice “Este programa no puede ser ejecutado en DOS”.

Sin embargo, aún no éramos tan buenos como para programar 100% en lenguaje máquina a velocidad mas o menos razonable, y ahí comenzó la aventura de buscar programación de Windows en ASM. En ese entonces el FASM tenía muy poco soporte y no nos hallábamos con sus terribles Macros. Existían sin embargo otros 2 caminos: MASM y NASM.

nasmlogo

El Netwide Assembler, mejor conocido como NASM era un ensamblador “popular” en el mundo de Linux (y escribo popular entre comillas porque en realidad a la gente de Linux no le interesa mucho el ASM) Su sintaxis era muy buena comparada con otros ensambladores de Linux y podía hacer código para DOS y Windows. Por un tiempo usamos este ensamblador, y aunque era excelente para programar nuestras viejas computadoras 486 con DOS, programar en Windows era demasiado complicado, pues necesitaba de un enlazador externo sumamente revoltoso de usar llamado ALINK para hacer programas compatibles con Win32. Eso sin mencionar que el NASM era sumamente ineficiente, era posible contar en segundos el tiempo que se tardaba en compilar un sencillo “hola mundo” y su ejecutable medía casi un mega completo. Además de que había demasiados pasos intermedios que no quedaba claro que hacían. Pero sobre todo, una cosa muy rara era el hecho de que un programa ensamblador tuviera su source code en C. Me imagino que como el C es el lenguaje de programación oficial de UNIX y todos sus descendientes lo hacían para mentener cierta compatibilidad. Al final decidimos abandonar el NASM porque a diferencia de otros proyectos de GNU Linux este estaba relativamente abandonado y sus contríbutors no parecía interesarles demasiado la programación en ASM, como a la mayoría de la gente que trabaja con Linux.

cajadelmasm

En cuanto al MASM o Microsoft Macro Assembler este en realidad casi no lo usamos. Sin embargo era necesario conocerlo muy bien porque la inmensa mayoría de los códigos de Ensamblador para Windows que encontramos estaban programador en él. Los tutoriales de Iczelion, los del Test Department, un Tetris en DirectX (del que hablaré dentro de poco) y la mayor parte de los códigos de las comunidades de Ensamblador para Windows fueron ensamblados con MASM. Lo siniestro del asunto es que Microsoft abandonó MASM desde mediados de los noventa y desde entonces ha sido mantenido con vida artificial por hábiles programadores de diversas partes del mundo. De hecho hay un programador conocido solo como Hutch que ha hecho mucho por mantener este viejo ensamblador funcionando en estos últimos años. Puede que lo que lo ha mantenido con vida haya sido su capacidad para generar viejo código máquina de 32 bits para los 486 pero de ahí en delante, el MASM no pasaba de ser un modelo antiguo con grandes remodelaciones de aficionados.

Al final solo quedaba el FASM, pero como ya se dijo los programas en Ensamblador para Windows eran muy pocos y casi todos estaban plagados de esas horribles macros que tanto fastidian a los principiantes. Por lo que en aquellos años la programación en ASM para Windows pasó a segundo plano para dar paso al desarrollo de software para la consola coreana de videojuegos mencionada en la entrada anterior.

De Vagabundo a Estudihambre

Y así pasaron un par de años hasta que mi familia me obligó a retomar mis estudios. En realidad no me interesaba estudiar y solo lo hice porque mi madre dijo que no se iba a morir hasta no verme titulado como el resto de mis hermanos, el si podría vivir o no de lo que estudiara le importaba, como se dice en México, 3 cacahuates. Y como tal, busqué una escuela cuya colegiatura me costara solo 3 cacahuates, donde nadie me conociera y sobre todo que al graduarme tuviera un título de ingeniero. Por obra y gracia de los dioses del tercer mundo encontré un lugar donde podía estudiar una carrera profesional por menos de 100 dólares americanos el semestre.

De esta escuela les hablaré otro día, lo que importa ahora es que a 3 semestres de haber entrado ahí el trabajo con los coreanos se fue por el retrete y sin jalarle. Por lo que furioso y con menos dinero decidí retomar la programación en ASM para Windows con todos los inconvenientes ya mencionados. Aún recuerdo como imprimí los tutoriales de Iczelion y el Space-Tris (Un Tetris en Ensamblador para Windows que usaba DirectX) y me encerré con lo que quedaba de mi antigua Pentium 100mhz de en ese entonces casi 10 años de antiguedad. Y como ambas fuentes de información estaban en MASM y yo programaba en FASM hizo falta de muchas horas con el BIEW y el OllyDbg mas documentos sobre el formato PE de Windows para lograr obtener toda la información que necesitaba y echar a andar los primeros códigos. Por desgracia ya era la segunda mitad de la primera década de este siglo y todo eso no me servía para mucho. En ese tiempo aprendí mucho de lo que actualmente se sobre como programar en ASM para Windows.

El Reto Final de los Vagabundos

Sin embargo la controversia seguía. Pues aunque ya era capaz de hacer las típicas aplicaciones GUI con Ensamblador aún faltaba el poder hacer verdaderos juegos, por lo que esa sensación de inferioridad no acababa de irse. Recuerdo especialmente una plática que tuve con el Julio en una época que habíamos considerado participar en un evento de animación y videojuegos llamado Creánimax. El decía que si queríamos participar íbamos que dejar momentaneamente el Ensamblador y programar en C++. Yo por supuesto como buen fundamentalista de la programación en ASM me opuse terminantemente a rebajarme a usar un lenguaje “para humanos”. Ahí fue cuando el Julio diera uno de sus discursos célebres:

–“Ya se que el ensamblador es como un Ferrari y que el C/C++ es un auto de calle como un Chevy (elijan el modelo que quieran) pero por ahora solo tenemos las llantas del Ferrari y no lo vamos a terminar de construir en un buen tiempo. Sin embargo ya tenemos completo el Chevy y puede llevarnos a donde queramos si arrancamos ahora mismo.”–

Palabras mas, palabras menos una semana después apareció con un modesto programa hecho en el tan odiado Visual Studio que escribía unos cuantos pixeles en la memoria de video y por una temporada estuvo haciendo algunas rutinas para manejo de sprites. Ahora que lo veo de lejos creo que si por lo menos hubiera hecho eso mismo con Code::Blocks y el MINGW (un derivado de GCC para hacer programas de Windows) lo hubiera aceptado un poco mas.

No estoy seguro de cuanto tiempo pasó entre eso y el momento en que yo por mi cuenta lograra hacer eso mismo programando completamente en Ensamblador; pero fue el suficiente para que el asunto de la participación en el Creánimax quedara olvidada. Finalmente, durante el verano del 2008 fue que logré hacer trabajar juntos al Windows Vista, los nuevos CPU’s multinucleo, el DirectX y al Ensamblador de manera verdaderamente eficiente de modo que podría tomar lo que mas me conviniera (abstracción de hardware de DirectX o programación directa de las Streaming SIMD Extensions) según considerara necesario. Luego de este evento tan trascendente en mi vida, ya no hubo mas necesidad de subestimar al Ensamblador a la hora de hacer proyectos serios. Sin embargo, apenas había aprendido a flotar en las orillas del océano y para ganar era necesario cruzar este a nado limpio. Aunque una de las cosas mas extrañas de esta aventura de programar en Ensamblador para Windows fue que los libros que mas me ayudaron a lograrlo no eran precisamente libros de Ensamblador, ¡Sino de Programación en C!. Por supuesto que estos solo me sirvieron para saber que era lo que estaban haciendo esos OpCodes porque al final donde los programadores de C veían esa horrible notación húngara yo solo veía agradables enteros de 32 bits y una que otra cadena ASCII-Z o Unicode.

Y como prueba aquí les dejo una captura de pantalla de una escritura en ensamblador directo a la memoria de video. El modo es el humilde 800 por 600 a 32 bits de colores. Cada uno de los renglones tiene una intensidad de color azul (256 intensidades). Los números a la izquierda son valores de 32 bits de una zona de la memoria. Para pintar estas lineas se usaron las instrucciones REP y STOSD de ensamblador. De modo que con esto se demuestra que no solo es posible programar en Ensamblador para Windows, sino que es posible obtener optimizaciones tan buenas como en la vieja época de los DOS Extenders. Y me haría falta esto y mas para poder manejar lo que estaba por ocurrir…

vramasm

Nota al margen: Esta foto la tuve que tomar con una camara digital porque no hay manera de capturar la pantalla con PrintScreen al escribir directo a memoria. Es necesario copiarla manualmente a un archivo de imagen.

Por cierto, y nada mas para insultar. Hasta ahora casi no he encontrado juegos que aprovechen las nuevas arquitecturas de nucleo múltiple a toda su capacidad. Muchos de los juegos actuales no serían capaces de desplegar sus famosas gráficas sin la ayuda de costosas tarjetas aceleradoras de video y la verdad es esa misma calidad de imagen sin el uso de las GPU’s ya era posible desde la época del Pentium 4 (si las hubieran programado en Ensamblador por supuesto). Por cierto, a finales del 2008 y principios del 2009 fue que logré escribir directo al sistema de video en ensamblador para Windows Vista. Y nada mas para seguir insultando, no tuve ninguno de esos problemas de los que tanto se quejan los lamers del .NET y plataformas similares. Y aunque usé algunos antiguos servicios del DirectX para evitar problemas con la protección de memoria, no tuve necesidad ni siquiera de descargar e instalar el SDK ni mucho menos ninguna de esas bibliotecas Wrappers (que ocultan las llamadas a DirectX) que tan de moda se han puesto hasta entre los autodenominados profesionales de la industria.

Y este es el punto donde se queda esta historia. Si todo va bien, para dentro de uno o dos años voy a tener con que darle a esto de los juegos. O antes si alguno de entre los que leen este blog quiere unirse para participar y llevarse su parte es bienvenido. Hay que recuperar todo el tiempo y dinero perdido. Y hay que moverse rápido porque los CPU’s de 64 bits ya llevan algún tiempo en el mercado y aunque los sistemas caseros de 64 bits actuales son bastante inestables, ya comienzan a ser aceptados por los consumidores. Parece que la barrera de los 4 gigabytes de memoria está por romperse. Y no puedo esperar por programar una computadora con 16 Exabytes (lo que mediria una memoria de 64 bits). Seguro en 20 años, pues igual de lejanos se escuchaban los 4 Gigabytes en 1985.

Y este es el fin de estas 4 historias sobre la programación en Ensamblador de 32 bits. Al final la única moraleja que puedo dejarles a ustedes es la siguiente:

–Si no puedes contra el enemigo…  ¡Desensámblalo!–

Anuncios

diciembre 13, 2009 - Posted by | Uncategorized | , , , , ,

2 comentarios »

  1. No lo hice con Visual Studio .NET, lo hice con MINGW.

    Yo habia propuesto hacerlo con C, porque el concurso estaba cerca, pero como no me hiciste segunda (y creo que nunca vas a hacerlo hahaha ), me desanime.

    Midiendo el tiempo invertido para hacer un juego por empresas reconocidas (6 meses minimo segun tus propias palabras),en ese entonces pense que era la opción más viable, además debes reconocer que en todos estos años hubo un tiempo que estuviste muy apatico y a veces hasta dificil en lo que respecta a la programación.

    Un videojuego no solo es la programación y tu bien lo sabes , importan mucho otros aspectos de los cuales poco se ha hablado en el blog, como el diseño, la historia, jugabilidad,sonido, etc…

    Ahora soy un poco escéptico con ciertos aspectos de la programación de videojuegos, si me dices vamos a hacer un pong, pues seguro lo puedo hacer en un par de horas, pero si me dices, vamos a competir contra un Halo,Grand Theft Auto, etc… ahí si te diría que me falta mucho.

    Y enfatizo que digo “ME FALTA”, no incluyo ni a ti ni a otro seguidor del blog.

    Saludos a todos

    Comentario por El Julio | diciembre 14, 2009 | Responder

    • Entonces esa imagen de la splashscreen de Visual Studio seguido del programa que abria los sprites sucedio en otra epoca cercana a aquella. Se me hace que el demo que pintaba puntos como si fueran estrellas que me mostraste tiempo despues eran los que realmente estaban hechos en MINGW. Creo que por mi mismo mal funcionamiento de la epoca se me cruzaron ambas imagenes.

      Ahora en cuanto a lo del concurso, de todas formas se cancelo por falta de participantes. En el 2009 se intento hacer pero estuvo tan mal organizado que es como si no hubiera existido. Asi que despues de todo no se perdio nada. Ahora en cuanto a lo que ‘vamos a hacer’ el asunto es que mientras mas tenemos mas podemos hacer. Entonces por ahora solo vamos a hacer simples rutinitas reutilizables. Por cierto, ya puedes comprobar la efectividad del metodo de organizacion de variables con el programa que muestra el hexadecimal de 32 bits. Espero pronto poder poner ese programa en este blog.

      Ahora que tanto escepticismo tendrias si digo “Vamos a hacer unas rutinitas…”

      Comentario por asm86 | diciembre 14, 2009 | Responder


Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: