El Ciego y el Mudo
–Programación sin Input ni Print–

Muchas veces al programar, pero sobre todo cuando se programa en Ensamblador, a veces se da entre el programador y la computadora una conversación entre un ciego y un mudo. La ilustración que acompaña a esta nota describe perfectamente esta situación, aunque la que yo estaba buscando era la de un ciego que entra a un baño público a orinar y no se percata de que un sordomudo está sentado en el WC frente al que está parado.
Mas específico, en los casos en lo que uno se inicia en la programación gráfica y no tiene acceso a funciones avanzadas de procesamiento de texto ni conversiones numéricas el monitor no sirve como dispositivo de salida para datos internos de la aplicación. Esto es lo mismo que si uno estuviera ciego. Al mismo tiempo, la computadora no puede leer entradas complicadas por el teclado y esto lo sabe cualquier estudiante que haya intentado procesar (por medio de un análisis léxico-sintáctico) cadenas alfanuméricas; en este caso, la computadora es como un sordomudo que no puede entender lo que le decimos. Por lo que para sostener un diálogo en esta situación es necesario usar un método de comunicación no convencional.
Mientras mas avanzo en esto de la programación en Ensamblador mas cuenta me doy del daño que produce haberse iniciado con lenguajes de ‘alto nivel’. Pues al menos en mi caso mi primer lenguaje al que le dediqué el tiempo suficiente para aprender fue el Qbasic que incluía el DOS en mi antigua Pentium 100 mhz. Las 2 instrucciones mas importantes para intercambio de datos entre el usuario y la computadora eran PRINT e INPUT. Con estas dos únicas instrucciones uno era capaz de darle datos al programa y ver que estaba pasando dentro de él. Y por supuesto que conforme aprendí otros lenguajes mas avanzados estos contaban con instrucciones equivalentes: readln y writeln en pascal, printf() y scanf() en C, cin y cout en C++ y así hasta que llegué al Ensamblador. Pues aunque habían funciones del BIOS o del sistema operativo no eran para nada tan sencillas de manejar como en su tiempo lo fueron INPUT y PRINT.
No hay peor ciego que el que no quiere oir.
Y de esto es de lo que trata esta nota, sobre como los métodos mas populares de entrada y salida en los lenguajes de nivel usuario no sirven en Ensamblador o el costo de implementarlos hace que no valga la pena su uso. Para poner un ejemplo cercano, el primer gran reto al que nos vamos a enfrentar en las siguientes notas de programación gráfica es el de no tener un método práctico y sencillo de implementar funciones de entrada y salida entre la computadora y el usuario. Pues las tradicionales funciones como las de MessageBox o las que involucran las GUI de Windows no funcionan a la hora de escribir directo a la tarjeta de video o si acaso llegan a funcionar su comportamiento no es nada predecible. Y aunque DirectX es compatible con los DeviceContext los resultados no son muy buenos. Como ejemplo la fotografía del monitor de la computadora aparecida en la nota “Revancha de 32 Bits” muestra el contenido de una sección de memoria relativamente pequeña, apenas unos 20 dwords. ¡Pero ocupa casi un tercio de la pantalla!. Por ejemplo, si quisiéramos mostrar una multiplicación de matrices de 4 por 4 con flotantes de 32 bits una pantalla completa no sería suficiente.
En resumen, los métodos usuales de despliegue de datos en pantalla no nos sirven de momento, la parte de entrada de datos no es dificil si escribimos estos directo en el source code o en algun área de datos inicializados; pero la salida es otra cosa. Una solución sencilla que se me acaba de ocurrir es la de sacar los datos que nos interesan por medio de un archivo binario y luego leerlos con cualquier editor hexadecimal externo a la aplicación desarrollada. Con esto nos ahorraríamos el esfuerzo de hacer todas estas cosas:
- Funciones de salida de texto a pantalla
- Conversiones entre datos binarios y ascii para su despliegue
- Rutinas de formato de texto para darle una apariencia medianamente legible
- Capacidades de ’scrolling’ de texto para desplegar grandes cantidades de datos en zonas pequeñas de pantalla
- Controles de actualización de salida para mostrar información de manera mas dinámica.
Y eso sin mencionar la ventaja que supondría tener un archivo de respaldo con la salida del programa en lugar de que estos datos se pierdan en cada inicialización. Creo que es oportuno mencionar que darle capacidades de texto a un sistema orientado a gráficos es algo que se hace en una etapa muy avanzada de desarrollo. Primero habría que conocer rutinas para manejo de sprites en un sistema tipo ‘raster’ o conocer de las matemáticas vectoriales en un sistemas mas avanzado. Así que por ahora quedémonos con los humildes trozos de datos binarios facilmente interpretados por un editor hexadecimal externo.
RAW DATA o datos sin curtir

Esta es la solución mas rápida y sencilla de aplicar para el problema de la salida de datos en nuestros primeros programas de manejo de gráficos. Un par de mejoras podrían ser poner valores predefinidos entre los datos para que sean mas fáciles de ubicar en la ventana del editor hexadecimal o inclusive hasta hacer un programa completo para interpretar esta clase de archivos de salida y presentarlos en un modo mucho mas legible. Esto aunque supondría un esfuerzo en si mismo evitaría sobrecargar el programa original con funciones de depuración no indispensables y permitiría una mejor reutilización de estos códigos en otros programas.
No recuerdo bien el nombre de esta técnica pero muchos llaman a esta clase de bloques binarios sin procesar “Raw Data”, que podría traducirse como Datos Crudos. El término Raw se usa para describir los materiales en su estado natural antes de ser procesados, por ejemplo pieles o madera. Ahora vamos a lo interesante, los detalles de la implementación.
Y esta es la mejor parte porque ¡Ya todo está hecho!. Si miran atrás encontrarán una nota en este mismo blog titulada “Darwin Digital” donde viene un programa en ensamblador que lee un archivo de texto y lo copia con otro nombre. Tranquilamente pueden arrancar la parte de ese programa que se encarga de escribir el archivo. Solo es cosa de definir un espacio en la sección de datos donde escribiremos la información que queremos ver y llamamos a la API de Windows para escribir el archivo.
Hasta ahora la única limitante que le veo, o debería de decir le veía a este sistema era el no poder visualizar datos en tiempo real. Pero pensándolo bien, en un sistema multitarea como lo es Windows bastaría con pasar de una aplicación a otra con ALT-TAB o el Task Manager y recargar el archivo en el editor hexadecimal. No sería tan rápido como escribir directo a pantalla pero al menos no estaríamos limitados al poco espacio para exhibir información que nos da la pantalla. Ahora que lo pienso, la ‘ceguera’ del programador en esta clase de situaciones es temporal, como la de alguien que se asoma a un cuarto oscuro con tesoros pero solo puede ver lo que sacó hasta que lo lleva a la entrada del mismo.
Es una pena que esto se me acabe de ocurrir hace apenas unas horas. De haber pasado esto hace una semana pude haber adelantado mucho en el tema de la Programación Gráfica en este blog. Estas últimas semanas no pude programar tanto como quería por motivos ajenos a mi control.
Informe ASM86[000]
Desventuras de un Programador de Ensamblador
Editorial:
Pues tal y como lo prometí en la entrada titulada “El Informe ASM86” aquí les va la primera de muchas entregas de este recopilatorio de chismes, rumores, memes de 4chan y otras cosas que a nadie mas importan sino a aquellos programadores poseidos por “ASModeus”, luego de esta presentación vienen las notas.
Noticias Mas o Menos Importantes
En esta sección vienen notas que mas o menos tienen que ver con la programación en Ensamblador pero que no tienen el peso suficiente para ser consideradas para una entrada completa.

Esta curiosa captura de pantalla proviene de un foro hablado completamente en ruso. En esta se puede leer perfectamente “http://asm86.wordpress.com” en una de sus lineas. Por lo que medio pude entender luego de echar mano del Google Translator, al parecer se trataba de un grupo de estudiantes que discutían la mejor manera de representar en decimal un número entero con signo en ensamblador. Uno de ellos posteó un código y por eso tuve una idea de lo que trataba. Por cierto, si nuestros amigos rusos leen esta entrada, les doy este consejo: si el entero binario que quieren repesentar primero lo convierten en formato packed BCD y luego lo usan como entrada de la funció que despliega hexadecimales de 32 bits van a tener el número en perfecto formato decimal con 8 cifras. Si quieren las 20 cifras que la FPU de los procesadores de Intel solo tienen que modificar el código para que procese 80 bytes en lugar de solo 32. Y a pesar de que no lo he intentado, sospecho que el formato Packed BCD incluye ya el signo en los 4 bits mas significativos. Para convertir un entero de 32 bits en Packed BCD solo tienen que usar las instrucciones FILD y FBST de la FPU. La mejor parte de usar la FPU para convertir a BCD es que nos ahorramos esa horrible función DIV, que para quien no sabe es verdaderamente complicada de manejar.
Si ustedes entienden ruso, o lo que es mas dificil la transcripciones del Google Translator aquí está el enlace:
http://forum.starline.lg.ua/index.php?showtopic=1116&st=0&gopid=16161&#entry16161
El gran misterio es como demonios programadores rusos dieron con este blog escrito en español habiendo tantas páginas web escritas en inglés que es el idioma que todo mundo en Internet conoce. Pero por ahora dejemos este asunto como está y esperemos que otros programadores del mundo encuentren util la información presentada aquí.
La Nota Lamer
Esta es la que mas promete, pues aunque el contenido de Ensamblador es prácticamente nulo si se expone a esos lamers que insisten en llamarse a si mismos “Profesionales de la Industria”.
Aunque tenía muchas cosas que contarles realmente no vale la pena desperdiciar espacio y tiempo de lectura. Solo voy a decirles en la sección de chismes que ya hay en Monterrey una “empresa” de desarrollo de videojuegos en la que los estudiantes pueden hacer sus prácticas profesionales. Que me acabo de encontrar en el YouTube unos videos de la flamante y prestigiosa carrera de la licenciatura en desarrollo de videojuegos de cierta universidad con la que tengo unas cuentas pendientes y que la filial mexicana de cierta asociacion internacional de programadores de videojuegos tiene “nueva” mesa directiva. La verdad es que no se podía esperar otra cosa del país de origen del PRI.
A Nadie le Importa…
Esta es la parte que puede ser omitida por default, a menos que quieran estar al tanto de mi glamorosa y emocionante vida social, rarezas que me encuentro en la calle y otras cosas que no aportan ningún beneficio para la humanidad.
Otra noticia que es mas o menos reciente es la de una pequeña red de trata de lamers con la que creo que voy a tener un pequeño choque. Este último asunto merece otro informe dedicado especialmente a esto. Por ahora aquí termina este primer informe, solo esperen a que pasen una o dos semanas y van a ver un significativo aumento en esta clase de notitas inservibles, que aunque no se comparan con las de programación, sirven para mantener este blog activo.
El Programador En Su Laberinto
–Como hacer un mapa de un programa en ASM–
Uno de los muchos requisitos que los héroes de la antiguedad debían de cumplir para ser considerados como tales era el de poder orientarse en los mas intrincados laberintos mientras se enfrentaban a toda clase de trampas y monstruos que los habitaban. Y por supuesto en ningún juego de aventuras que se respete pueden faltar esta clase de retos, junto con sus guerreros feminoides y las interminables horas dedicadas a ganar puntos de experiencia. En el caso de la programación no solo en ASM sino en casi cualquier lenguaje de programación en el que se tenga que escribir código la situación es muy parecida a lo que se cuenta en el mito de Teseo y el Minotauro. Veamos todos estos parecidos.

Cuando uno comienza un programa, o al menos lo es en mi caso, tengo idea de lo que quiero hacer; pero no dea de como va a funcionar. Igual que al recorrer los primeros cuartos de un laberinto uno sabe que tiene que llegar del origen al destino.
Conforme el programa crece se van agregando funciones y estructuras de datos que son mas o menos independientes entre si, igual que cuando uno va internándose en los primeros cuartos del laberinto.
Mas adelante comienzan los problemas cuando unas funciones comienzan a depender de otras, si bien esto ayuda a evitar código redundante hace que un error en las funciones mas primitivas afecten las mas nuevas, tal y como cuando para llegar a un cuarto en el laberinto hay que cruzar otros tantos.
Luego, comienza el problema de los identificadores, tanto nombres de variables como de funciones, es muy común olvidar a que procedimiento pertenece cada una y esto es especialmente peligroso con las variables locales pues puede haber cientos de variables diferentes con el mismo nombre pertenecientes a diferentes métodos; igual que cuando uno cree que todos los cuartos y pasillos del laberinto parecen iguales y recorremos una y otra vez los mismos lugares sin llegar a ninguna parte.
Finalmente, la estructura del programa se vuelve tan grande y enredada que es necesario regresar continuamente sobre las instrucciones ya escritas para saber lo que estamos haciendo tal y como ocurre en un laberinto cuando en verdad nos perdemos. Y es cuando estamos completamente perdidos cuando nos topamos cara a cara con el Minotauro.
El Encuentro con el Minotauro
Así es, cuando el programa se ha vuelto demasiado complicado en su estructura es cuando aparecen los errores mas peligrosos y resolverlos no es algo que se haga en un solo sitio, sino que casi siempre involucran recorrer muchos procesos diferentes repartidos en diferentes partes del programa a menudo separadas por miles de lineas de código. Igual que un verdadero encuentro con el Minotauro sería una mutua cacería entre dos depredadores donde luego de cada choque aquel que resultara mas lastimado huyera tan solo para recobrar fuerzas y volver a atacar a su oponente a traición.
Y eso es lo que hace tan diferente la resolución de problemas dentro de un programa tan dificil como una persecución dentro de un laberinto. Y a diferencia de la lucha en terreno despejado, para sobrevivir al combate en un laberinto no basta con saber pelear. Es necesario conocer bien el lugar. Saber donde se localizan los atajos, los sitios para esconderse y las trampas ocultas. Si uno sabe todo esto puede emboscar y acorralar al Minotauro para evitar que se escape o incluso engañarlo para hacerlo correr directo a ese precipicio que solo nosotros sabemos donde se encuentra. Por eso lo mas importante es conocer cada detalle del laberinto y bajo ninguna circunstancia perdernos dentro de él.
Dibuja un Mapa del Laberinto
Esto parece obvio; la pregunta es como demonios nos orientamos ahí dentro. De acuerdo con el mito griego, Teseo amarró el extremo de una larga madeja de hilo a la entrada del laberinto y conforme se internaba en este lo iba desenredando. De ese modo cuando quisiera regresar tan solo tenía que seguir ese hilo. Ahora, si Teseo hubiera tenido papel y lapiz probablemente pudo haber dibujado su propio mapa y marcado en este los lugares por donde ya había pasado. Y al igual, un programador necesita llevar su propio mapa del código en el que está trabajando. Hace mucho en este mismo blog hablé sobre este problema pero en esa época mi solución era desarrollar un editor de texto con funciones avanzadas de análisis del source code para ayudarnos con esta tarea; y aunque la idea aún no es por completo desechada es demasiado complicada para implementarla en el corto plazo. Por lo que aquí les presento un método para llevar un buen mapa de nuestro programa con tan solo una humilde hoja de cálculo.
Esta es la captura de pantalla de una hoja de cálculo común y corriente. La primera columna contiene el nombre del símbolo y las siguientes información sobre este, como por ejemplo su ancho en bits, el tipo de información que contiene y por supuesto una descripción de unas pocas palabras. Y cuando digo símbolo no me refiero nada mas a las variables, sino también al nombre de las funciones, etiquetas de salto, estructuras, constantes y cualquier otra cosa que pudiera ser nombrada dentro del programa.
El modo de usar esta hoja es muy simple, tan solo se sueltan escribiendo su código como siempre y el el momento que declaren una variable, programen alguna función o hagan referencia a alguna constante simbólica solo tienen que “darla de alta” en esta hoja de cálculo no solo con el nombre, sino su tipo de dato y algún breve comentario sobre la misma. Conforme el programa crezca van a necesitar información como el nombre exacto de un determinado identificador, sobre todo si están usando la infame Notación Hungara tan común en la programación para Windows o el orden en que una función recibe sus argumentos. No hay problema, tan solo hay que ordenar las entradas de la hoja de cálculo en orden alfabético para encontrar ese símbolo de manera rápida. Ahora veamos algunas de las ventajas que tiene este sistema:
- Evita duplicidad de variables.- Es muy común que cuando el programa crece demasiado aparezcan identificadores con nombres muy parecidos que hacen cosas completamente diferentes. Si hay una variable que ya hace algo que queremos hacer podemos encontrarla a la hora de “dar de alta” esta en la hoja.
- No mas errores de llamados de función.- Personalmente yo pierdo mucho tiempo buscando una y otra vez el lugar de declaración de esa función tan solo para ver detalles sobre el orden y tipo de sus argumentos, sobre todo cuando no recuerdo el nombre exacto. Esta hoja ayuda a encontrarlos sin tener que moverse en el código cada vez. Además de ser especiamente útil a la hora de llamar funciones externas como las del sistema operativo cuya documentación rara vez se encuentra en Ensamblador.
- Se evita el problema del hardcode y los ‘magic numbers’ sin enredarse aún mas.- Dicen los programadores mas experimentados que uno nunca debe de poner constantes numéricas dentro del código porque luego es mucho mas dificil hacer cambios, sin embargo el hecho de usar constantes simbólicas puede hacer que el código se vuelva mucho mas enredado y dificil de leer sobre todo para los principiantes. Podemos poner los nombres de estas constantes simbólicas junto con su verdadero significado numérico en la hoja y así siempre tendremos a la mano ambas informaciones mientras programamos. Esto es especialmente util cuando trabajamos con la API del Windows, DirectX o cualquier otro sistema que haga uso de nombres extraños para las constantes.
- Da una idea de la complejidad del programa.- Supongo que nadie se imaginaría que un simple Hola Mundo en Ensamblador para Windows iba a necesitar de ¡19 variables!. Con este sistema uno puede darse una idea de que tanto se ha complicado el programa y se tiene toda la información a la mano para simplificarlo.
- Tiene Disponibilidad Inmediata.- Esta es la mejor parte, pues no hay que hacer nada mas que abrir una hoja de calculo de Microsoft Excel, o si no les alcanza para su copia pirata de reforma usen Calc de OpenOffice. Y para moverse entre el editor de ensamblador y el organizador de variables no hace falta mas que oprimir la combinación de teclas ALT + TAB
Este sistema puede ser ampliado de muchas formas, por ejemplo pueden hacerse mas columnas con información sobre los símbolos y variables o guardar información sobre los archivos usados en los proyectos mas grandes. Solo recuerden que cada que ingresen un valor hay que reordenar todos los elementos para que sea mas sencillo encontrarlos cuando los necesitemos, mientras que en el editor de ensamblador no nos hará mas falta que las propias funciones de búsqueda e intercambio de texto para mantener el programa bajo control.
Bueno ya escribí demasiado, en la próxima entrada hablaré sobre una manera muy sencilla y de rápida implementación para comunicarse con un programa cuando el teclado y la pantalla no están disponibles. Por ahora mejor me pongo a escribir código y espero esta vez no perderme en él.
El Informe ASM86
–Los Peligros Mas Allá del Teclado–
Como ya dije en alguna nota anterior, mas programadores de Ensamblador caen por su pobre habilidad de manejar los recursos del mundo real que por su falta de habilidad para abrirse camino en el ciberespacio. El siguiente proyecto trata de un nuevo tipo de entrada en este blog llamada precisamente “Informe ASM86” y será una especie de apartado de noticias mas o menos impactantes que aunque no lo parezcan se relacionan directamente con la programación en ASM. Algo similar a esos infames pasquines fotocopiados que circulaban en la época anterior a la Web 2.0. La razón por la que hago esto es porque, como ya se habrán dado cuenta hace buen tiempo que no publico algo decente y esto, mas que ser una excusa se trata de una advertencia de lo que pueden encontrarse en el camino que aunque muchos de ustedes no lo acepten puede dejarlos fuera de combate y dejarlos en manos de un Tratante de DBA’s como los que me acabo de enterar que existen aquí en Monterrey.
<
En el Informe ASM86 pueden encontrar desde porquerías como este Goatse que me encontré en el HEB de Linda Vista en Monterrey hasta los nuevos chismes sobre el mercado de lamers en el norte de la república pasando por algunas cuentas pendientes que tengo con una cierta universidad y algunos asuntos que sin ser precisamente cosas personales tienen que ver muchísimo con la programación en ASM. Tan solo para empezar, y ahora que según mis cálculos a muchos ya les dio flojera seguir leyendo, tengo que contarles un secreto sobre mi y que es mi mayor motivo de verguenza hasta ahora:
Como recordarán en las notas mas antiguas yo fui expulsado de una cierta Universidad estatal hace cierto tiempo en parte por mis ideas sobre programación, pasé un par de años como ermitaño electrónico perfeccionando mis habilidades y buscando aventuras en la red y luego por presiones familiares tuve que retomar mis estudios en un lugar donde nadie me conociera. Bueno, mi horrible e inconfesable secreto es que ahora mismo estoy entrando a lo que debería de ser mi último año de estudios en este lugar. La parte de la verguenza es la siguiente: el significado de lo que es ser ingeniero en computación (y lo escribo con minúscula) ha decaido mucho desde la última década del siglo veinte y lo que en su origen era considerado un científico capaz de dominar las poderosas computadoras ahora no es mas que una ayudante de contabilidad sobrevalorada y alquilable a la que no baste exigirle un título profesional, sino que ahora ponen requisitos que no tienen nada que ver con la habilidad en las computadoras.
Empresa Importante Solicita…
Yo quiero que me digan en que empleos serios para gente con post-grado se piden requisitos como el de excelente presentación, menor de 25 años, preferentemente mujer y eso que ahora llaman “tener buen trato con los clientes”. La respuesta es en un area donde hay 25,000 egresados anuales de este tipo de carreras tan solo en este país. Y donde de lo único que puede trabajar alguien que realmente le interesaban las computadoras es administrando bases de datos y haciendo frontends para sistemas de cuentas por cobrar. Y luego se quejan de que aquí en México no se desarrolla tecnología de verdad. Eso por no mencionar a los que no les alcanza con lo que les pagan en la iniciativa privada y tienen que trabajar en el sector público tan solo para tener seguro de gastos médicos.
Ante tal podredumbre (o debería de decir “pobredumbre”) en la que me tocó caer, mi reto personal fue el de programar por mi cuenta y lograr algo antes de graduarme. Y aunque no he alcanzado aún el nivel que esperaba, estas pequeñas victorias que me ha traido este humilde blog me hacen sentir un poco menos miserable conmigo mismo en este aspecto. La verdad es que me parece un insulto que alguien me exija a mi un título universitario para darme un empleo habiendo decenas de miles de personas ahí afuera que tienen uno y que deberían de poder hacer las cosas mucho mejor que yo. La verdad es que este documento lo estoy tramitando únicamente por motivos familiares y solo a mi familia es a la que le importa que lo tenga o no.
¿Y tú lo haces por dinero?
En mi opinión personal, estudiar una carrera universitaria con el propósito de obtener un buen empleo no es muy diferente a casarse por dinero. El único deber de las instituciones de educación superior es (o debería de ser) el desarrollo y divulgación del conocimiento por el conocimiento mismo, independientemente del uso que la gente pueda darle una vez desarrollado. Y los que entran a estudiar una carrera universitaria sea cual sea su única meta debería de ser entender y desarrollar lo mejor que puedan aquel conocimiento que la institución pone a su alcance. Ya una vez que tenga suficiente dominio de la materia ese estudiante decidirá que camino seguir y que hacer con el conocimiento ganado. Las universidades no pueden rebajarse a ser meras fábricas de mano de obra de las empresas y si se empeñan en seguir haciéndolo va a llegar el día en que ya no haya verdaderos científicos desarrollado tecnología porque los pocos capaces de hacerlo van a acabar dando clases a futuros administradores de bases de datos… creo que al menos en México ya es demasiado tarde.
Por eso, voy a utilizar este último año que me queda en este tipo de ambientes para hacer todo el mal que pueda lo que esté en mis manos para levantar la programación en Ensamblador aunque sea en esa pequeña escuela que me dio refugio cuando ya no podía seguir estudiando en ninguna otra parte. Y para ello no solo voy a programar sino a trabajar en este Informe ASM86 para mantener al tanto a todos los posibles programadores de ensamblador que leen este blog de las posibles amenazas que pueden enfrentar cuando se alejan de la relativa seguridad del teclado de sus PC’s.
Ya para terminar, a todos aquellos que recién se titularon o están por hacerlo les dejo esta frase que aparecía en el primer Street Fighter:
What Strength!!
But don’t forget there are many guys like you all over the world…
Realidad y Ciberespacio
–No todo lo que es real tiene existencia física–
Hace ya tiempo que quiero escribir sobre esto, pero los 2 anteriores intentos de entrada de blog me parecieron demasiado falsos y pretensiosos como para ponerlos aquí. Pero ahora que mi confiable Nokia 9290 quedó completamente inutilizable tuve que conseguir un teléfono un poco mas modesto. La ventaja de este nuevo equipo es que aunque no cuenta con tantas capacidades como mi viejo 9290 tiene unas interesantes capacidades mutimedia que por supuesto que tengo pensado en usarlas para el mal. O en este caso, para ponerlas al servicio de este blog.

A diferencia de este 9290, el nuevo equipo cuenta con una cámara completamente silenciosa y puede tomar foto y video con la suficiente calidad como para ilustrar cosas dignas de ser exhibidas aquí. La cuestión es que es lo que voy a capturar. Y aquí es donde entra el siguiente tema: La barrera entre el mundo real y el ciberespacio.
Actualmente, tratar de explicarle a un menor de treinta años lo que es el ciberespacio es como hablarles de magia a los elfos, pues es algo con lo que han nacido y conviven todos los días tanto para trabajar como divertirse. Y de acuerdo con William Gibson autor del Neuromancer el ciberespacio es “una alucinación voluntaria” generada por computadora. Un espacio que no existe fisicamente y solo es formado por puntos de colores en una pantalla pero con el que se puede interactuar de un modo muy similar a como uno lo hace con entidades materiales. No hay que esperar a tener el cerebro conectado con cables a una consola electrónica para experimentar el ciberespacio, ahora mismo están ustedes haciéndolo. Si se encuentran leyendo estas letras directo de la pantalla, para su cerebro no hay ninguna diferencia entre esto y leer las letras impresas en una hoja de papel. Solo que sin hoja de papel. Aunque no porque este blog no tenga una existencia física significa que no es real. La información tiene la propiedad de ser real sin necesidad de existir en el plano material. Del mismo modo, alguien que usa un editor de textos además de leer interactua con el sistema y crea un texto que de nuevo no tiene existencia física. ¿Significa esto que el texto no existe o que el escritor en realidad no hizo nada? Supongo que esto ya es filosofía. Ahora pasemos a lo que algunos insisten en llamar programadores.
“Una Alucinación Voluntaria”
Un programador es un ser humano con existencia física que no solo interactúa con el mundo real y el ciberespacio como cualquiera, pero a diferencia de los usuarios mundanos el programador es un hacedor. Puede crear programas de computadora, que son lo mas cercano a entidades vivas que pueblan el ciberespacio. Es una especie de mago e inventor que puede aparecer cosas de la nada que no solo tienen esa existencia inmaterial del ciberespacio sino que gozan de cierta autonomía sin llegar a estar completamente vivas pero al no ser completamente estáticas tampoco se puede decir que sean entidades completamente muertas.
Hay muchas clases de programadores, tantos como necesidades de software existen en el ciberespacio y en lo que a nosotros nos concierne, el programador de Ensamblador es especial porque vive exactamente en la frontera entre este mundo real y el virtual. Apenas justo después de los ingenieros electrónicos que trabajan con circuitos y señales electrónicas que existen en el mundo físico y antes de los usuarios que interactúan con imágenes echas de puntos de colores como si se tratara de objetos reales. Y eso es lo que hace tan diferentes a los programadores de ASM, pues deben de ser capaces de ver mas allá de esa “alucinación voluntaria” formada por pixeles y llegar a los números que se almacenan en los circuitos internos de las computadoras, y una vez que son capaces de esto, podrán ser capaces de manipular y alterar esa realidad artifical conocida como el Ciberespacio.
Una Realidad Obligatoria
¿Y que es lo que pasa afuera? La verdad es que fuera del ciberespacio el programador es un ser poco menos que indefenso, pues materialmente no es mas que un simple humano que escribe en el teclado de una computadora no muy diferente a la que cualquiera tiene en su casa. Mas allá del teclado este ser no tiene nada que le de ventaja sobre otras personas, no tiene la fuerza física del obrero ni los bienen de los comerciantes y como su actividad es muy barata tampoco cuenta con las grandes sumas de dinero de los banqueros. Si acaso, su única ventaja sería cierta capacidad para manejar información que dicho sea de paso en la vida cotidiana no sirve de mucho. Algunas personas dicen que lo mas importante de un programador es “pensar de manera lógica” ¿Es que acaso se puede pensar de manera no lógica? Si uno no aplica la lógica en realidad no está pensando, los humanos pueden sentir, imaginar o responder a impulsos primitivos pero ninguna de esas cosas es pensar. Y hasta donde yo se todos los humanos tienen la capacidad de pensar en mayor o menor medida, entonces. ¿Qué puede hacer un programador en el mundo real?
Aquí es donde entran las capacidades de mi nuevo teléfono, pues si bien en el ciberespacio lo peor que puede pasarle a un programador es que su software no funcione es en el mundo real donde realmente corre peligro de ser destruido. No voy a ponerme a hablarles de dramas de la vida porque para eso existen programas cómicos como el de Silvia Pinal y una interminable variedad de Talk Shows no menos hilarantes. Sino de cosas que realmente pueden desgraciarle la vida a la gente que programa en Ensamblador, algunas de estas cosas por supuesto son asuntos escolares, laborales y de convivencia con humanos, así como las mil peripecias que un programador puede vivir en el Tercer Mundo. La verdad es que tengo un buen de cosas que contarles de esa parte del mundo real que afecta directamente a la programación en Ensamblador y que mejor que ahora que tengo el equipo para hacerlo con estilo.
Solo como avance, diré que este nuevo segmento será similar a un pequeño noticiero o periódico al estilo antiguo donde cada entrada no va a medir mas de una hoja (la mitad de cualquiera de estas entradas) que podría ser leída en uno o dos minutos por cualquier persona que haya cursado algunos años de escuela primaria. En cuanto acabe de arreglar una falla en la sincronización del teléfono con la PC pondré la primera entrada de esta especie de noticiero de nota roja para programadores de Ensamblador.
DirectX en Ensamblador
–Como Llamar al DirectX desde un programa en ASM–
Pues ya ha sido un año de decir cosas sin sentido en este blog. Conforme pasa el tiempo la gente que viene a este sitio comienza a preguntar cosas mas interesantes y no todos son simples estudiantes en busca de alguien que les haga la tarea. Sobre todo en las últmas fechas viene mas gente preguntandome como hacer cosas interesantes. Y ya que los 5 o 6 seguidores mas fieles de estos escritos ya están en capacidad de entender los temas mas avanzados es hora de comenzar con el tema de la programación gráfica en Ensamblador. Y el tema de hoy es el de DirectX en ASM.
Antes de que los programadores mas hardcore me agarren a tomatazos quiero explicar primero como es este asunto. Primero si uno quiere programar el hardware directamente en una computadora casera tiene 2 caminos, el primero es hacer su propio sistema operativo (yo ya lo intenté) y el segundo es mediante algunas funciones mas o menos ocultas del DirectX que casi ningún Game Developer “Profesional” (odio esa palabra) utiliza. Si optan por hacer su propio OS puede que tengan éxito pero en general la gente no le interesa demasiado desinstalar su fiel Windows cada vez que quieran correr un juego.
Lo interesante de la historia del DirectX es que al menos en su origen parece haber sido desarrollado con la programación en Ensamblador en mente. Pues las funciones mas primitivas casi no hacen nada por si mismas. De hecho el DirectDraw lo único que hace es devolver información muy general sobre el hardware de video y manipulación de esta memoria a nivel muy pero muy elemental. Las únicas funciones que se ven mas o menos sofisticadas son aquellas que transfieren bloques de bits (BitBlT como dicen en “La industria”) y son suceptibles a ser aceleradas por hardware. Pues esta es una de las funciones de aceleración de video por hardware mas antiguas que se conocen. Aunque no me extrañaría que transferir bloques de memoria con MOVSD fuera mas rápido. Actualmente DirectX se ocupa casi por completo del rendering de una escena y el desarrollador solo tiene que asegurarse de que los parámetros de las funciones cumplan con ciertas condiciones para garantizar compatibilidad. Aunque el nuevo DirectCompute de Dx11 se ve bastante prometedor para la programación de verdad. Pero de esto último hablaré muy pero muy en el futuro.
Supongo que cualquier aficionado a las computadoras sabe que es el DirectX y no voy a dedicar una entrada entera para explicarlo. Lo primero que debemos tener en cuenta es que el DirectX funciona bajo el Modelo Objeto Componente, abreviado COM. Esta tecnología es una de las mejores cosas que Bill Gates ha hecho por la programación en Ensamblador desde tiempos del MASM. Pues permite que las llamadas a los Objetos COM (en este caso DirectX es un objeto COM) no dependan del lenguaje de programación usado. Es pocas palabras, esto es lo que permite que podamos recurrir a los servicios de DirectX sin importar que lenguaje usemos, bien puede tratarse de C, C++, C# o incluso ASM. No menciono otros lenguajes para no comenzar peleas pero construir una interfaz COM desde un lenguaje cualquiera es casi tan sencillo como hacer un arreglo de enteros de 32 bits.No hacen falta directivas raras de compilación, descargas de SDK’s (al menos no en ASM) ni mucho menos bibliotecas de enlace de esas que tantos problemas les dan a quienes tratan de iniciarse en esto de la programación de videojuegos.
La mejor parte del COM es que no hace falta una sección de importaciones tan grande y complicada para su manejo como en el caso de las tradicionales llamadas a la API de Windows. Sin embargo, un típico COM es bastante mas complicado de inicializar que una típica llamada a una función de la API. Afortunadamente para nosotros, DirectX tiene un sistema de inicialización semi automática que nos evita eso. Por ahora, nuestro primer programa va a usar la versión mas antigua que existe del DirectDraw, lo va a inicializar y luego lo va a desactivar, para decepción de los lamers este demo no va a mostrar otra cosa mas que una simple ventana con un mensaje que va a decir si se pudo o no inicializar.
Ahora Vamos con el Source Code
Primero el programa inicializa una ventana casi como cualquier otra. Ya saben, primero se obtiene el Module Handle, la posición de la linea de comando, se llama a Winmain, se declaran las respectivas estructuras de mensaje y parámetros de ventana, se da de alta la clase de ventana con RegisterClassEx y se crea la ventana con CreateWindowEx. El resto ya lo saben y si no lean las notas de inicios del 2009 de este mismo blog. Bueno, la parte que nos interesa es esta:
push 0
lea eax, [directdraw]
push eax
push 0
call [DirectDrawCreate]
;inicializar directdraw
mov eax, [directdraw]
push eax
mov eax, [eax]
call dword [eax + 8]
;directdraw::release()
Esto es lo mismo que hacer hResult =DirectDrawCreate(NULL, iDirectDraw,NULL); en C++. Y esto es la parte mas interesante de esta entrada, pues mientras que para usuarios de otros lenguajes casi no hay diferencia entre una llamada a la API de Windows y una llamada a uno objeto COM nosotros los programadores de ASM podemos ver la enorme diferencia entre un estilo de llamada y otra.
Lo que este programa hace es lo siguiente:
- Inicializa DirectDraw y obtiene la “Interfaz” al objeto DirectDraw recién creado
- Llama a la función DirectDraw::Release(); para liberar el objeto COM
- Irnos al demonio del modo usual.
Obsérvese la enorme diferencia que hay entre la llamada a DirectDrawCreate, que es una simple llamada a la API de Windows y a DirectDraw::Release(); que es una llamada a una función miembro del objeto DirectDraw.
Este método es muy parecido a como trabajan los equipos de sonido de carátula removible de algunos automóviles. Cada uno de los botones de esta carátula activan un interruptor que controla las funciones del equipo. Para mi este modelo es muy complicado de explicar.

Otro simil podría ser esos intercomunicadores de los departamentos en los que uno oprime un botón para comunicarse con cada uno de los cuartos. Lo importante de este modelo es que no solo se logra independencia del COM con la aplicación que la llama, sino que es posible modificar el COM sin necesidad de cambiar la aplicación que usa sus servicios. Mas adelante hablaré sobre las maravillas del COM. Por ahora voy a seguir explicando como llamar a DirectX desde Ensamblador.
Desde el punto de vista de un programador de Ensamblador, una interfaz COM no es mas que un entero de 32 bits que representa una localidad de memoria. En ese lugar hay una estructura con información de dicho objeto, la parte mas importante es su tabla de funciones. El primer DWORD de esa estructura es a su vez otra posición de memoria que indica donde se encuentra esta tabla. Todos los objetos pertenecientes a una misma clase hacen las mismas cosas y para no desperdiciar espacio todos tienen un apuntador a una misma tabla de funciones. Esta tabla es un array de enteros de 32 bits donde cada uno a su vez es una posición de memoria a las funciones que nos interesan. El proceso para hacer una llamada a una función de un objeto COM desde Ensamblador es el siguiente:
- Empujar los argumentos al Stack como si se tratara de una llamada a funcion como cualquier otra com PUSH
- Empujar como último de los parámetros la “interfaz” que es el DWORD que representa al Objeto COM
- Obtener la posición de la tabla de funciones asociada a ese objeto, este es el primer DWORD de la definición del objeto. En el ejemplo, se carga en EAX la interfaz primero y luego se hace un MOV EAX, [EAX]
- Finalmente se hace una llamada Base mas desplazamiento. Donde la base es un registro general que contiene la posición de la tabla de procesos de ese objeto COM y el desplazamiento es el número de función multiplicado por 4 (por ser DWORDS).
Por ahora aquí le dejo, mas adelante vamos a ver mas sobre el manejo del COM. Sin embargo, esta entrada es mas que suficiente para aquellos que quieran programar sus juegos en Ensamblador para Windows. Solo necesitan una poca mas de información sobre el COM y el archivo de ayuda que incluye el DirectX SDK. Recuerden que es importante hacer ingeniería inversa con los desensambladores a este y todos los ejemplos ejecutables que les de en este blog o en la comunidad virtual.
Como Imprimir un Entero de 32 Bits en ASM
printf(“Imprimir en ASM no es tan facil como tu crees”);
El semestre en las universidades termina y con ello baja la cantidad de visitantes, dejando solo aquellos que vienen por gusto o porque realmente les interesa el ASM. Esta vez traigo un programita que convierte un valor binario de 32 bits en una cadena ASCII-Z.

Ya se lo que se han de estar preguntando los que no estan muy familiarizados con la programación en ensamblador: ¿Porque este desperdicia espacio en una tontería como esta? O peor aún ¿Y que este idiota no sabe que los números son diferentes a los “strings”?
Mientras mas avanzo en esto del Ensamblador mas me doy cuenta del daño que causa a a los programadores principiantes el empezar su aprendizaje con lenguajes de “alto nivel” (como me fastida ese término). Por todos es bien conocido el daño que hace iniciarse a programar con BASIC y todos sus descendientes y tal parece que cada nueva versión de BASIC tiene nuevas y mas novedosas maneras de echar a perder a los programadores mas jóvenes. No cabe duda de que el daño hecho por iniciarse en este tipo de lenguajes es muy dificil de remediar. Si me pusiera a enumerar todos necesitaría otras 3 entradas nada mas para el puro BASIC, pero en este caso creo que voy a blasfemar un poco.
Todos saben que como radical que soy, tengo muy poco respeto por la mayoría de los lenguajes autodenominados de “alto nivel”. Excepto por el viejo C que es el que mas se acerca al ASM. Sin embargo, para quienes se inician programando en C o alguno de sus derivados mas amistosos topan con piedra a la hora de comenzar a programar en ASM. Pues cosas que son relativamente sencillas en estos lenguajes son completamente diferentes, cuando no imposibles en ensamblador. Esta lista merece su entrada a parte pero el asunto a discutir ahora es la modesta función printf( );
printf(“La suma de %d + %d es igual a %d”,numero1, numero2, resultado);
Veamos los parámetros: el primero es una cadena de texto con signos de control que son remplazados por el contenido de las variables numéricas llamadas numero1, numero2 y resultado. Pero este proceso no es directo, primero la función debe de procesar por medio de un aceptor la secuencia de signos que se encuentran entre las comillas dobles e interpretar los signos de control como instrucciones. ¡En realidad esta sencilla cadena de caracteres puede considerarse un programa completo!. Y lo que dice es: Toma los 3 números cuyos valores te envío por el Stack, conviertelos en strings decimales e intégralos con el resto del string y luego le dices al sistema operativo que los despliegue. Eso sin mencionar la comprobación exhaustiva de tipos de las variables ni los formatos numéricos en los que debe de ser mostrado. De hecho, la leyenda de que una sola instrucción de C se convierte en cientas o miles de instrucciones en ASM es cierta sobre todo por instrucciones como printf(); y scanf();
Bueno, ahora que ya saben que un printf no es tan sencillo como parece vamos con el código:
;BIN2ASC.ASM
;Escrito por Mario Salazar el 11 de diciembre del 2009
;http://asm86.wordpress.com
;http://itzasm.ning.com
;Programita que despliega un numero de 32 bits en hexadecimal
;por medio de MessageBox. Para compilarlo con FASM solo presione
;la tecla F9. El numero solo puede ser cambiado en el codigo
;Lean el archivo bin2asc.xls para una referencia de las variables
format PE GUI
entry start
section '.code' code readable executable
start:
mov [eax_bin], 1234abcdh
;cambia el 1234abcdh por el numero que quieras entre 0 y 2^32
call bin2asc
;llamada a la funcion que convierte ese numero en cadena ascii-z
push 0
push debug_caption
push eax_ascii
push 0
call [MessageBoxA]
;mostrar una MessageBox que despliegue el numero
push 0
call [ExitProcess]
;terminar el programa
bin2asc:
pusha
;guardar los registros generales en el stack
xor eax, eax ;prepararse para el ciclo y
mov ecx, 8 ;cargar valor binario en edx
mov edx,[eax_bin]
lee_binario:
mov ebx, 0fh ;extraer los 4 bits mas bajos
and ebx, edx ;con una mascara de bits
mov al, [ebx + digitos]
push eax ;usar esos 4 bits como indice
shr edx, 4 ;a la tabla digitos
loop lee_binario ;por cada 8 numeros
;obtener 8 simbolos ascii y guardarlos en el stack
mov ecx, 8
mov edi, eax_ascii ;apuntar edi a la cadena ascii
escribe_binario:
pop eax
mov [edi], al
inc edi
loop escribe_binario
;sacar los simbolos ascii del stack y
;guardarlos en la cadena ascii
popa
ret
;restablecer los registros generales y terminar proceso
section '.data' data readable writeable
eax_bin dd 0 ;valor binario a convertir
debug_caption db 'Hex de 32 bits:',0 ;nombre de la ventana
eax_ascii db '00000000',0 ;cadena de salida
digitos db '0123456789ABCDEF' ;arreglo de simbolos hexadecimales
section '.idata' import data readable writeable
dd 0,0,0,RVA kernel_name,RVA kernel_table
dd 0,0,0,RVA user_name,RVA user_table
dd 0,0,0,0,0
kernel_table:
ExitProcess dd RVA _ExitProcess
dd 0
user_table:
MessageBoxA dd RVA _MessageBoxA
dd 0
kernel_name db 'KERNEL32.DLL',0
user_name db 'USER32.DLL',0
_ExitProcess dw 0
db 'ExitProcess',0
_MessageBoxA dw 0
db 'MessageBoxA',0
section '.reloc' fixups data readable discardable
En realidad la mayor parte del source pertenece al viejo PEDEMO.EXE del FASM. Pero no he “encapsulado” este “método” para que fuera mas sencillo de entender y a la vez mas dificil de lamear. Para compilarlo solo cárguen este programa en el IDE del FASMW y opriman F9. Pueden cambiar el número 1234abcdh por el que ustedes quieran ¡Incluso si lo dan en formato decimal o como una palabra de 4 letras!. Si hacen lo de las palabras con 4 letras (muchas de las cuales suelo gritarle a los lamers todo el tiempo) no olviden ponerla entre comillas dobles. No se asusten si de pronto alguna aparece al reves, se debe a algo llamado Little Endian que explicaré (de nuevo) otro día.
El programa tiene 3 elementos de datos:
eax_bin.- Es un espacio en memoria de 32 bits donde se va a guardar el dato a desplegar
eax_ascii.- Array de 9 bytes. Ocho son para los digitos y el ultimo en un cero binario que indica el fin de la cadena ASCII-Z
digitos.- Este es el mas importante. Es un array de bytes donde cada uno representa uno de los 16 digitos ascii que serán usados para formar la cadena de texto.
Ahora vamos con las instrucciones:
Antes y después de la función se guardan y restauran los valores de los registros generales con PUSHA Y POPA. Luego de guardarlos se escribe el entero de 32 bits en el registro EDX y en ECX se escribe un 8 en preparación para el ciclo de lectura que ha de repetirse 8 veces.
Hay un ciclo que lee el valor de 32 bits en porciones de 4 bits cada una, este ciclo está entre la etiqueta lee_binario: y la instrucción loop lee_binario. Para extraer los 4 bits mas bajos del registro EDX se hace un AND entre este y EBX que poco antes fue cargado con el valor 0Fh (quince decimal y 00001111 en binario) El resultado de este AND deja en EBX los 4 bits mas bajos del registro EDX y el resto los pone a cero. Esto es lo que los programadores de ASM llamamos “máscara de bits”.
Ahora viene lo interesante: Para convertir esos 4 bits en un dígito ASCII con una sola instrucción de lenguaje Ensamblador usamos EBX como offset del arreglo digitos. De modo que estos 4 bits (que solo pueden tomar valores entre 0 y 15) nos den la posición de memoria de su correspondiente dígito ASCII una vez que se sumen a la posición de memoria indicada por la etiqueta digitos. La instrucción que hace esto y guarda el resultado en la parte baja del acumulador EAX es MOV AL, [EBX + digitos]
Luego de esto, el acumulador completo se guarda en el stack con push y luego se hace un desplazamiento binario hacia la derecha de 4 bits en EDX con SHR EDX, 4. Con esto ahora los 4 bits mas bajos en EDX corresponden al siguiente dígito hexadecimal a transformar. Esto se repite 8 veces hasta que se obtienen todos los valores ASCII para formar la cadena hexadecimal de 32 bits.
La siguiente es bastante sencilla, primero se carga en ECX otro 8 para escribir los 8 digitos del hexadecimal de 32 bits. A continuación se carga en el registro EDI (Extended Destination Index) la posición de memoria de la zona donde vamos a escribir la cadena ASCII. Entonces, por cada ciclo vamos a ir sacando valores de la pila con POP EAX y escribimos los 8 bits mas bajos en la posición guardada por edi con MOV [EDI], AL e incrementamos el ‘puntero’ EDI con INC EDI para ir avanzando en la cadena.
Luego de estos 2 ciclos restauramos los registros generales con POPA y devolvemos el control al llamador con RET. Es importante siempre restaurar los registros generales en Windows, sobre todo EBX, ESI y EDI antes de que el Windows vaya a hacer cualquier cosa, de lo contario podemos desatar su ira y nos echará abajo la aplicación.
Una cosa mas, por si no lo han notado en el primer ciclo los digitos de 4 bits se leen comenzando por el menos significativo pero a la hora de escribir se comienza por el digito mas significativo. Esto es posible porque usamos el Stack. Y como todos saben de la clase de ensamblador con Solis el primer elemento en entrar a estas estructuras es también el último en salir.
Ya para terminar, es importante poder convertir enteros binarios en cadenas ASCII porque la mayor parte de los sistemas operativos (o en este caso la API del Windows) no pueden representar números binarios facilmente. Además de que un mismo número binario puede ser representado en muchas formas diferentes dependiendo del sistema numérico (decimal, hexadecimal, fraccionario, etc.) mas adelante veremos como desplegar un número binario en formato decimal. En realidad solo basta con agregar 2 instrucciones y un dato de 1 byte a este mismo código. Les aconsejo que sean organizados con sus viejos códigos y los reutilicen tanto como les sea posible porque los programas escritos en ASM pueden llegar a ser enormes en source aunque su ejecutable tan solo mida unos pocos kilobytes.
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.

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.

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.

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…

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!–
Vagabundos de 32 Bits
¿Era ese el final de los Programadores de Ensamblador?
Esta historia es continuación de la nota anterior llamada “Desterrados de 32 Bits” que a su vez es continuación de “Revolución de 32 Bits” y cuenta uno de los episodios mas deprimentes en la historia de la programación en Ensamblador de principos de este siglo.

En la última entrada se cuenta como de la noche a la mañana, se volvió casi imposible programar en Ensamblador para computadoras con Windows basados en tecnología NT (como el 2000, ME y XP) y como muchos tuvieron que dejar de lado la programación en Ensamblador y rebajarse a manejar bases de datos para poder sobrevivir. Y de como mis compañeros programadores y yo decidimos hacerle frente a este destierro sin obtener lo que se dice los mejores resultados en el proceso. Sin mas, aquí está la historia:
El asunto no podía quedarse así, por lo que en ese entonces reuní a lo que entonces era mi pequeña banda de forajidos computacionales y en una junta tomamos una de las decisiones que, aunque tuvo muchas cosas buenas retrasó nuestro avance en el desarrollo de videojuegos por al menos nueve años. Ahí, frente a unos demos de DirectX, recuerdo especialmente uno de una calabaza de halloween que desplegaba un Framerate de 120 FPS, nos preguntamos:
¿Continuamos con la programación directa del hardware o nos metemos con DirectX?
¡Demonios! Si pudiera regresar el tiempo justo a ese instante me abofetearía a mi mismo hasta que solo me funcionaran el sentido del oido y el sentido común y me gritaría a mi mismo:
¡No seas 9*n3+@5! ¡Es perfectamente posible programar para Windows en Ensamblador!
Pero en ese entonces tenía un concepto muy equivocado sobre lo que era programar para Windows. Creía que la única manera de desarrollar para las versiones mas avanzadas de este sistema operativo era con herramientas como el Visual Studio y similares. Las cuales en ese entonces (o sus equivalentes de ese entonces) aunque eran buenas resultaban muy caras, extremadamente difíciles de conseguir, con infomación casi nula y aún bien dominadas el rendimiento del producto final no se comparaba con el de una aplicación programada completamente en Ensamblador. Por lo que, confiados en nuestra habilidad para programar en ASM tomamos una decisión tan valiente como ingenua: ¡Nuestros juegos debían de ser capaces de ejecutarse sin sistema operativo!
Hoy en día es mas o menos conocido el concepto de Live CD entre los aficionados a Linux. Y para los que no saben, un live CD es un disco que uno pone en una computadora y que es capaz de correr una aplicación completa sin necesidad de alterar en lo mas mínimo el sistema operativo instalado, y se usa para versiones de prueba de sistemas operativos. Nuestro plan era hacer juegos que funcionaran de la misma manera. Durante ese tiempo, que abarcó mas o menos 2 años aprendimos muchísimo sobre como hacer un sistema operativo y, al igual que cuando intentamos hacer un compilador propio y nos topamos con FASM, esta vez nos topamos con MenuetOS. Un interesante sistema operativo de Europa Oriental programado completamente en Ensamblador. Aprendimos mucho de esa experiencia, aunque mas hubiéramos aprendido de haber sabido hablar ruso. Algunas de las hazañas que conseguimos en ese entonces fueron:
- Arrancar una PC sin sistema operativo por medio de un Bootloader en Floppy y CD
- Hacer controladores de discos y periféricos para ese bootloader.
- Entrar al modo protegido desde ese bootloader
- Tomar control sobre el misterioso BIOS de 32 bits.
- Manipular el BUS PCI y todos lo periféricos conectados al mismo.
- Manipular las tarjetas de video de aquel entonces compatibles con el estandar VESA 2.0 y superior.
- Mover grandes cantidades de datos con el DMA de 32 bits.
- Y muchas cosas igual o mas impresionantes que al final no nos sirvieron para mucho.

Al final, ya cuando teníamos la capacidad de desarrollar software mas o menos decente que corriera desde un live CD (por cierto, en esa época las grabadoras caseras de CD eran tan caras como una computadora de escritorio) nos topamos de narices con que la gente no aceptaba ningun software que no corriera en Windows. Era una ironía que aún teniéndo la capacidad de desarrollar un sistema operativo completo si hubiéramos querido eramos incapaces de programar unos humildes juegos.
A partir de entonces no ocurrió nada bueno, salvo el haber levantado una pequeña oficina en un local que había permanecido abandonado durante cuarenta años. Y que a pesar de tener serias carencias nos sirvió bien para continuar nuestras investigaciones por los primeros 2 años de este siglo XXI. En ese corto espacio jugamos a ser una empresa de 3 (5 si contamos al Samuel y a Aldape) programadores sin documentos ni ganancias. Pero que logramos uificar todo lo que hasta entonces habíamos desarrollado.
Sin embargo, al pasar el tiempo y no lograr avances que fueran redituables el grupo se fue debilitando. Ya no éramos mas los programadores capaces de trabajar en un demo por 3 días seguidos de campamento en la oficina, algunos se vieron obligados a trabajar por hambre y necesidad. Eso sin mencionar que en ese entonces fue cuando me expulsaron de la universidad cuando ya iba en mi penúltimo semestre. El juicio fue algo traumático pero mas traumáticos fueron los meses antes y después del mismo. Y como ya comenté, no podré poner un pie en mi antigua facultad hasta bien entrado el 2024. Pero si regreso no va a ser como estudiante. Por cierto, mas o menos a la mitad del siguiente año fue cuando nuestro grupo de desarrollo acabó de desmoronarse por completo. Aunque aun nos veíamos ocasionalmente para planear estrategias que nunca llevábamos a cabo. Y aunque habíamos caído, aun no estábamos muertos.
Y aun estaba por venir lo peor…
Los siguientes dos años fueron los peores, no tiene caso que comente mis tragedias personales pero solo voy a decirles que en ese entonces fue cuando comenzó mi odio contra los lamers, pues en ese tiempo no encontraba trabajo ni como barrendero y el ver como todos los empleos en computación se los llevaban gentes cuyas únicas habilidades eran copiar querys, escribir documentos html (y no precisamente con un editor de texto), hacer clientes con editores de Visual Basic y trabajar con hojas de cálculo era algo que me enfurecía mas allá de los límites del razonamiento humano. Aún recuerdo como disimulé el asco al saludar de mano a un jefe de recursos humanos que tenía unas horribles manchas en la piel.
Y así pasé ese tiempo hasta que un día me llegó el chisme de que al otro lado del mundo alguien estaba desarrollando una nuevo consola de videojuegos y que no encontraba programadores. Esa pequeña aventura fue lo que me mantuvo vivo durante esos años negros y aunque no terminó como me hubiera gustado,si me hizo sentirme mejor conmigo mismo y me ayudó a reconstruir parte de mi antiguo equipo de desarrollo. Dicho aparato era conocido como GP32 de una empresa de Corea del Sur llamada Gamepark ubicada en Seoul. Espero poder escribir sobre ese asunto un día de estos. Pero supe que lo peor había pasado cuando, durante una sesión de programación con esta consola portatil, el buen Julio dijera:
–Te ves mucho mas repuesto que como te veías en los años de universidad… ¡En especial el último!
En fin, en el tiempo en que tuve esa consola coreana en mis manos recuperé mucho de lo que había perdido en años anteriores y si no fuera porque mi familia me obligó a rehacer mis estudios muy probablemente estaría escribiendo este blog desde algún lugar de Corea del Sur. Sin embargo, a pesar de esta gran victoria semipersonal (pues el Julio también colaboró muy de cerca) la programación para sistemas Windows había quedado abandonada durante siete años y dudo que en los 2 próximos años pueda hacerse algo que valga la pena vender. Apenas hace un año y luego de meses de ingeniería inversa y otras artes oscuras que no se si sea seguro mencionar en público es que logré hacer funcionar el ensamblador en una computadora con CPU de nucleo múltiple en Windows Vista. Y es ahora cuando realmente puedo retomar todo lo que dejé pendiente hace ya tanto tiempo.
Derrotados pero no muertos
Como se dijo en la nota anterior, este regreso a la programación en Ensamblador para Windows se debe en gran parte a los esfuerzos de grandes programadores como Iczelion, el autor del FASM Thomasz Grysztar, gente de sitios como asmcommunity.net y otros muchos mas que a partir de mucha investigación lograron devolverle su merecido lugar a la programación en ASM. En la siguiente entrada se hablará de este feliz regreso. Sin embargo, apenas se había descubierto el camino a seguir. El recorrerlo y llegar hasta el final era un esfuerzo de proporciones épicas, mismas que se detallarán en la siguiente nota donde además de eso se contará como los programadores de Ensamblador regresamos al territorio del que alguna vez fuimos cruelmente expulsados.
Destierro de 32 Bits
C:\>RUN\DOS\RUN>
Esta es la continuación de la entrada anterior titulada “Revolución de 32 Bits”.
La última nota trató sobre el como las PC’s equipadas con procesadores 386 y superiores abandonaron lentamente la programación en 16 bits para dar paso a aplicaciones mas avanzadas de 32 bits. Y como el mundo tuvo que esperar casi 10 años para ver juegos que realmente aprovecharan el hardware de estos entonces poderosos equipos. En esta parte de la historia se cuentan unos años horribles en los que llegué a pensar que era el fin de la programación en Ensamblador para computadora personales.
Corrían los últimos años del siglo veinte, poco a poco las conexiones de tipo Dial Up se volvían inoperantes y los primeros monitores LCD (de esos que si uno no estaba parado directamente de frente a ellos no se veían) comenzaban a aparecer. Esa era una época maravillosa en la que el DOS y el Windows 95 cohabitaban en la misma computadora y existía la controversia de que tanto uno dependía del otro. Tiempos en que el Windows NT solo existía en equipos empresariales y aunque era muy estable no servía para jugar. En ese tiempo aún había juegos que para jugarlos adecuadamente había que salirse del Windows. Pues correrlos desde dentro de este sistema, aunque era posible disminuían severamente su desempeño. La razón de esto era el Modo Virtual 86
Modo Virtual 86

Las computadoras de 32 bits (no recuerdo de momento a partir de que CPU) tenían una modalidad interesante de operación llamada Virtual 86 Mode, en que podían imitar no solo uno, sino a una multitud de sistemas de 16 bits y ejecutarlos como una subtarea independiente. De este modo era posible correr al mismo tiempo varias instancias del DOS con sus respectivas aplicaciones sin por ello salirse del Modo Protegido. Esto le dio mucha vida artificial a estas viejas aplicaciones aún a pesar de que hacía mucho tiempo que los CPU’s 8086 habían dejado de fabricarse. Sin embargo, cuando una aplicación de Modo Real trataba de inicializar el Modo Protegido desde el Modo Virtual 86 pasaban errores muy feos, como el Famosísimo Fallo de protección General, Ejecución de instrucciones privilegiadas, fallos de página y otras cosas peores cuya única solución casi siempre era un reset de la computadora completa. Eso sin mencionar que aunque esto no ocurrirera, uno solo tenía acceso a una minúscula fracción del poder de procesamiento y memoria del sistema. Por lo que las aplicaciones de 16 bits ejecutadas en el Modo Virtual 86 rara vez daban buenos resultados. Aunque siempre estaba la opción de reiniciar la computadora en modo MS-DOS.
¿Qué estaba haciendo Bill Gates mientras tanto?
Resulta que en su diseño original, Windows no estaba preparado para suministrar lo necesario para hacer buenos juegos. Su GDI (Graphics Device Interface) estaba pensada con la seguridad en mente y no en el alto desempeño que los juegos requieren. Por lo que, y esto lo leí en viejos libros de historia, intentaron hacer una biblioteca de funciones de 32 bits desde al menos el windows 3.1. Dicha mejora era conocida como WinG pero no tuvo la aceptación esperada y los buenos juegos siguieron corriendo en Modo Protegido desde MS-DOS con ayuda de los Dos Extenders. Sin embargo, un poco mas adelante, Bill Gates finalmente aceptó que la única manera de lograr que los buenos juegos fueran desarrollados para Windows era dándo un acceso mucho mas DIRECT-o al hardware.
Inicios del DirectX.

Antes de entrar en detalle, hay que explicar primero el concepto de Overhead. Como en su origen las computadoras personales tenían muy pocos componentes realmente estandar aparte de un CPU Intel o compatible, era muy común crear capaz de delegación intermedia para facilitar la comunicación entre los dispositivos mas dispares sin cambiar los códigos originales. Por ejemplo, en tiempos del DOS, si uno quería escribir un pixel en pantalla primero tenía que llamar una función de la biblioteca de gráficos de C llamaba BGI(o cualquier otra biblioteca de gráficos) llamada putpixel(); que recibía las coordenadas X, Y y el color. Esta a su vez llamaba al sistema operativo para dar la órden de pintar el pixel, luego el sistema operativo llamaba al BIOS que ejecutaba la interrupción 10h y luego de hacer una complicada y tardada serie de validaciones al fin escribía el mentado puntito de color en la pantalla. Este proceso era tan lento que uno podía hacer un ciclo anidado para pintar la pantalla y podía ver como esta cambiaba de color lentamente. ¡Y pintar una pantalla completa de 320 por 200 tardaba casi un minuto!. Sin embargo, con ensamblador bastaba con conocer la posición de la RAM de Video y escribir un pixel era tan rápido como mover un byte a una posición de memoria. Eso sin contar que existían muchos recursos para manejar la tarjeta de video para hacer animaciones rápidas (de momento recuerdo por lo menos tres). El asunto era como dar acceso a los programadores a esta velocidad sin necesidad de salir del Windows. Y fue así como nació DirectX
Como su nombre lo indica, la idea original tras el DirectX era darle a los programadores el acceso mas directo posible al Hardware sin comprometer la protección de memoria del propio Windows. Mientras que intentaban ahogar los problemas de compatibilidad de hardware con capas de abstracción y emulación de hardware. Al principio DirectX fue un fracaso, pero no tanto porque fuera una mala idea, sino porque la mayor parte de los recursos del sistema estaban siendo usadas por el resto de las aplicaciones. No fue sino hasta la aparición del DirectX 5 que se empezaron a ver juegos para Windows mas o menos decentes. En ese entonces, los juegos de 32 bits soportados en los DOS Extenders ya comenzaban a oler a muerto.
C:\RUN\DOS\RUN>
Los vaqueros del viejo oeste solían decir que no había mejor indio que el indio muerto, y yo digo que el mejor de todos los Windows fue el Windows 98 SE, pues permitía explotar un sistema Pentium III a plena capacidad con todo y sus puertos USB en menos de 30 megas. Además de ser muy estable y ser el último que tenía la opción de reiniciar en Modo MS-DOS. Con un sistema como este fue que mi grupo de desarrolladores renegados aprendimos una buena cantidad de cosas sobre computación. Sin embargo. Sin embargo, con la llegada del temido Windows NT y sus derivados a las computadoras caseras, esta maravillosa era terminó. No mas juegos de 32 bits que tomaban el control absoluto del sistema. De hecho, en esa época, mientras jugaba el juego Hexen en una PC Pentium III con Windows ME apareció una pantalla sobre un error en algo llamado WinOldAp. De acuerdo con una poca de investigación, Winoldap era un servicio del sistema operativo que permitía correr aplicaciones de la época descrita en la entrada anterior “Revolución de 32 Bits” en este caso me enteré de que estaba muerto hasta que el mismo Windows me lo había informado.
…llegó un momento en que llegamos a creer que ese era el fin de la programación en Ensamblador para computadoras caseras…
Por cierto, y hablando del Windows ME, fue a partir de esta versión del sistema operativo de Micro$oft que la feliz armonía entre el Windows y los programadores de juegos que usaban Dos Extenders (o que entraban al modo protegido por su cuenta) se acabó. A partir del Windows 2000 y el ME ya no había manera de salirse del Windows y tomar el control absoluto del sistema como antes. Recuerdo que hubo una pequeña guerra entre mi grupo de amigos programadores por que sistema instalar en nuestras computadoras. Pues un sistema posterior al Windows 98 no nos permitía programar como lo habíamos hecho hasta entonces. Y la peor parte es que todas las herramientas para desarrollo en Windows eran inadmisibles dados nuestros métodos de trabajo. Llegó un momento en que llegamos a creer que ese era el fin de la programación en Ensamblador para computadoras caseras por lo que, como abandonar la programación en ASM no era una opción decidimos hacer lo mejor que se nos ocurrió: ¡Programar en Ensamblador para otras plataformas! Aunque eso significara crear la nuestra propia.
Y en ese entonces fue cuando se dio nuestro destierro de la programación en Ensamblador para computadoras caseras. Aunque en ese tiempo hicimos muchos avances en otras áreas relacionadas con el Ensamblador que se mencionarán en la siguiente entrada. Pero eso no nos salvó de experiencias terribles que poco a poco fueron debilitando al equipo aunque sin llegar a acabar con él por completo.
En la siguiente entrada se contará de que fue de la programación en Ensamblador (o al menos la parte que me tocó vivir) durante los primeros años del presente siglo y como gracias a los esfuerzos de grandes hackers como Iczelion y otros cuyos seudónimos no alcanzo a recordar los programadores de Ensamblador pudimos regresar a la escena de la computación casera de la que alguna vez nos sentimos desterrados. Pero entre ese tiempo, muchos de nosotros nos convertimos en poco menos que vagabundos y esos oscuros años son los que se narrarán mas adelante.
