Programación en Lenguaje Ensamblador

-El Verdadero Lenguaje de las Máquinas-

Programación Gráfica para Principiantes

–Solo necesitan papel, lapiz y calculadora–

“Programación Gráfica” Dos palabras que en el pasado hicieron que muchos dedicaran su vida a las computadoras y hoy se han convertido en una especie de creencia malentendida entre muchos desarrolladores aficionados. En las comunidades de desarrollo de videojuegos, la tercera cosa que mas me hace enojar despues del esnobismo y el abuso del outsourcing es esa idea de que programación gráfica es aprenderse todas las funciones de una API o hacer scripts para un engine. En esta entrada voy a concentrarmé en las gráficas mas que en la programación. Tanto así que van a ver que es posible aprender sobre gráficas sin necesidad de una computadora.

Seguro pensarán que es algo imposible. Pero en la imagen que acompaña esta entrada pueden ver todo lo que necesitamos. Así como una descripción de su equivalente dentro de una computadora. Para los que no reconocen estos objetos les diré para que es cada uno:

Libreta de cuadrícula: Puede ser de cuadro de 5 o 7 milímetros. Estas hojas cuadriculadas es lo único que necesitamos para simular la manera en que se comporta un monitor de computadora así como sus registros y memoria interna. Existe un tipo de hoja conocida como cuadro alemán cuyos cuadros son aún mas grandes y que es particularmente util para aprender sobre estructuras de datos en una memoria de computadora. Pues cada cuadro es lo suficientemente grande para escribir un byte con 2 cifras hexadecimales.

Lapiz y borrador: Es importante que el lapiz sea facil de borrar y que la goma no maltrate demasiado el papel, pues va a ser necesario escribir y borrar varias veces los mismos trazos y números. Así como hacer algunos cálculos manuales.

Calculadora: Esta va a ser nuestra unidad de procesamiento gráfico. No es necesario que sea una calculadora muy poderosa aunque algunos modelos capaces de trabajar con sistemas de matrices puede acelerar muchísimo este trabajo. Por cierto, la calculadora electrónica mas sencilla que puedan encontrarse trabaja de manera muy similar a nivel abstracto a una unidad de punto flotante básica con la que vienen equipados de fábrica los procesadores de Intel.

Y eso es todo, no necesitamos mas poder computacional que una modesta calculadora escolar, un cuaderno de cuadrícula y lápices. Con esto podemos comenzar a estudiar lo que son las gráficas por computadora desde cero. Lo primero que haremos será tomar una hoja y dibujar un cuadro lo mas grande que sea posible y que mida la misma cantidad de cuadritos de ancho que de altura. Es importante basarnos en la cuadrícula de la hoja en todo momento. Una vez que tengamos el cuadro estaremos listos para aprender el primer concepto de las gráficas por computadora: Sistemas de coordenadas.


Sistemas de Coordenadas

Coordenadas Físicas: El primer sistema de coordenadas que debemos conoces es el sistema de coordenadas físicas. Para los que no saben matemáticas básicas y desconocen el concepto de coordenadas. Estas son una secuencia de números que indican un punto en el espacio de manera única. En el caso de nuestra hoja se trata de un espacio plano de dos dimensiones. Una dimensión es la horizontal y otra la vertical. Podemos obtener la posición de cualquier punto a partir de un par de números de manera única. No va a haber otro punto al que correspondan esos mismos dos números (en ese orden) ni ese mismo punto. Ese par de números nos indican la cantidad de pasos para llegar a un punto. La pregunta es de donde comenzamos a contar los pasos y en que dirección.

Como estamos trabajando en coordenadas físicas y la hoja trata de imitar el monitor de una computadora. El punto del que se comienzan a contar los pasos y que es conocido como Origen se va a ubicar en la esquina superior izquierda. El lado superior e izquierdo de ese cuadro serán nuestros ejes del sistema de coordenadas físicas. El primero es el eje horizontal que crece a la derecha y el otro el vertical que crece hacia abajo siendo (0,0) el punto superior izquierdo del cuadro. Ya se que así no es como se manejan los verdaderos sistemas de coordenadas pero esto es lo mas parecido a como trabajan los monitores de las computadoras.

Como ubicar puntos individuales. Contrario a lo que casi todos ustedes están pensando. Los cuadros que componen la cuadrícula de la hoja no representan los pixeles. En realidad los sitios en donde se cruzan las lineas que forman la cuadrícula representan los centros de los pixeles. Esto tiene un porqué. A nivel matemático los puntos en el espacio no solo carecen de dimensión sino que son infinitamente pequeños. Mientras que los pixeles son cuadros bidimensionales con ancho y altura perfectamente medibles. En gráficas por computadora se trabaja con lo que los matemáticos llaman Números Reales, y se aproximan por medio del formato de Punto Flotante. Pero no se preocupen, voy a tratar de explicar estos temas de manera que cualquier estudiante de educación pública básica pueda entenderme.

Digamos que el cuadro que dibujamos mide 20 por 20 cuadros. El punto de arriba a la izquierda que corresponde con el origen (0,0). Significa que partiendo de ahí damos 0 pasos a la derecha y cero hacia abajo. Recuerden que los puntos son las intersecciones de las lineas de la cuadrícula y no el interior de los cuadros. El punto mas lejano del origen seria la esquina inferior derecha a las que corresponderian las coordenadas (20, 20). Jueguen un rato a ubicar puntos por sus coordenadas y a obtener las coordenadas de puntos dentro de esa ‘pantalla’

Si les interesa esto de la programación probablemente se han preguntado como le hacen los juegos 3D para poder desplegar el mismo juego en diferentes resoluciones y tipos de pantalla. La respuesta son las coordenadas lógicas normalizadas. En matemáticas se llama normalizar a poner una cantidad en un rango entre cero y uno (no es la definición oficial pero con eso nos basta) Esto tiene aplicaciones muy interesantes como en este caso el poder manejar imágenes que no cambien de tamaño cuando hagamos un cambio de resolución. Las coordenadas lógicas de dispositivo son el primer nivel de abstracción en las gráficas vectoriales. En este sistema el origen sigue estando en (0,0) pero el punto mas alejado es (1,1). Aunque técnicamente es (0.9999999,0.9999999) quedando todos los demás puntos en un rango de cero a uno. De este modo el centro de la pantalla corresponderá siempre con el punto (0.5,0.5) sin importar que resolución en pixeles manejemos.

Como ya se habrán dado cuenta para cambiar de un sistema a otro es necesario hacer una serie de cálculos. Para convertir las coordenadas físicas a coordenadas lógicas dividimos las coordenadas del punto (x,y) por el valor máximo que las ‘x’ y las ‘y’ puedan tomar. Por ejemplo si estamos trabajando con una cuadrícula de 10 por 10 y queremos convertir el punto físico (5,5) basta con dividir entre 10 y obtener (5/10, 5/10) que es igual a (0.5, 0.5). Para convertir de coordenadas lógicas a físicas hacemos el proceso inverso y multiplicamos de modo que (0.5 * 10, 0.5 * 10) es igual a (5, 5). Experimenten con cuadrados de diferentes tamaños y verán como los puntos siempre se mantienen en las mismas posiciones unos respecto a otros sin importar el tamaño del cuadro.

Sistema de Coordenadas Mundiales

Si ustedes pertenecen a esa rama de los otakus que se interesa por programar videojuegos lo mas probables es que no se hayan percatado que algo no está bien en el sistema de coordenadas que acabo de describirles. Y es que por tradición los sistemas coordenados usados en matemáticas tienen su origen en el centro y el eje vertical (conocido como el eje ‘y’) crece hacia arriba y no hacia abajo. Para que me entiendan, un verdadero sistema de coordenadas se parece al dibujo de cabellos cruzados con el que cuentan las miras de los rifles sniper en cualquier FPS. En otra entrada voy a hablar de lo importante que es esto pero por ahora solo tienen que saber que necesitamos de este sistema para que los cálculos nos funcionen. Para convertir coordenadas lógicas de dispositivo a este sistema es necesario primero restar 0.5 a x y para que el origen quede en el centro del area de trabajo. Para voltear el eje ‘y’ basta con multiplicarlo por -1. De nuevo, para convertir a coordenadas de dispositivo a la x se le suma 0.5 y a la ‘y’ primero se multiplica por -1 y a ese resultado se le suma 0.5. En una entrada posterior se van a repasar estas sencillas fórmulas.

Por cierto, aunque estamos trabajando con una hoja de papel plano en realidad hemos definido un espacio de 3 dimensiones. El eje Z es perpendicular a la hoja y crece a medida que los puntos se alejan de ella. Todos los puntos pueden tomarse como que su coordenada Z es igual a cero.

Si todo va bien voy a seguir con estas notas. Como dije alguna vez, tan solo escribo aquello que me hubiera gustado encontrar cuando comenzaba a programar y para que la gente le tenga respeto a las computadoras. Como esta entrada ya quedó muy extensa voy a dejar para la siguiente los temas de los sistemas de coordenadas. Y para los newbies que creen que no necesitan nada de esto porque tienen acceso al unreal engine (o Unity si es que no les alcanza) créanme que tener esta base teórica les va a resultar de mucha utilidad para al menos saber que es lo que hacen esos scripts que copian y pegan de los foros de desarrollo.

septiembre 30, 2011 Posted by | Uncategorized | , , , | 8 comentarios

Poor Programmer Episodio Doble

–Esto ya camina… ¡Ahora a correr!–

Esta vez les traigo dos episodios seguidos de la serie Poor Programmer. En el primero de estos dos se habla por fin de la manera de conseguir y manejar las constantes que normalmente no son parte del compilador. Como ya mencioné antes es importante conocer el valor numérico de las constantes simbólicas que tanto API’s como sistema operativo utilizan pero también es peligroso caer en los famosos números mágicos. Aquí se resuelve este asunto de una vez por todas.

En este otro video se muestra como usar una inofensiva hoja de cálculo para mantener el control del programa. Al principio parece sencillo mantener en la cabeza todos los símbolos de un programa. Pero en el caso del ensamblador, cuando el programa supera las 1000 lineas la cantidad de símbolos es inmanejable y este video muestra como echar mano de este recurso a la hora de programar. Para mas detalles sobre esta técnica lean la nota llamada “el programador en su laberinto”.

Por cierto, acabo de cambiar la manera de nombrar los videos porque los títulos anteriores no decían nada sobre el contenido del video. Ahora se incluye un título mas o menos descriptivo. Lo que se encuentra en los paréntesis cuadrádos es el número de reto y de episodio. Por ejemplo en lugar de escribir Poor Programmer Reto 1 parte 12 ahora se escribe Poor Programmer [r01p12] “Cazadores de Constantes”. De ese modo es posible describir de lo que se trata el episodio y a la vez tener algo que nos de idea de continuidad.

¿Qué sigue? Supongo que acelerar el desarrollo ahora que voy a tener un poco mas de tiempo. Hay tanto por hacer y tan poco tiempo. Pues cada que pasa el tiempo me parece que estoy perdiendo mi toque, o por lo menos mi capacidad para programar como antes lo hacía. A pesar de que por ahora las circunstancias parezcan tan favorables.

julio 4, 2010 Posted by | Uncategorized | , , , , , | 2 comentarios

Poor Programmer Reto 1 Episodio 9

–Como llamar a las DLL’s de Windows en FASM–

¿Qué esperaban? ¿Que mi próximo video saliera hasta dentro de un mes y no mostrara nada de código? Pues se equivocaron. Tengo suficiente material para sacar un video cada semana durante el próximo mes y dada la buena respuesta que tuvo el último video voy a seguir con este nuevo formato.

Aún recuerdo hace ya años cuando aprendí a programar en ensamblador para Windows por medio de la aplicación de la Ingeniería inversa que la parte mas dificil de todas fue sin duda (en ese entonces) la de lograr que una aplicación lograra interactuar con el sistema operativo sin problemas. Esto que en apariencia es sencillo no era tan evidente en un entorno multitarea y mucho menos sin un SDK adecuado. En este video que es la continuación del anterior se detalla toda la sección de importaciones. Recuerden que este programa no contiene ni una sola macro.

Para los que ponen en su perfil de las comunidades de desarrollo de juegos que saben ensamblador nada mas porque en su escuela copiaron el mismo viejo ejemplo de 16 bits que comienza con MOV AX, @DATA tengo que decirles que las llamadas al sistema operativo en Windows son completamente diferentes a las del viejo DOS. En Windows existen grupos de procesos que pueden ser llamados por cualquier programa. Por ahora no voy a dar una explicación muy detallada de lo que es una DLL o Dynamic Link Library pero en este video van a ver porqué se les llama bibliotecas de enlace dinámico. Porque los programas se enlazan a estas en el momento de su carga e incluso pueden hacerlo a media ejecución con algunas llamadas especiales al sistema operativo.

Por ahora solo tienen que saber que si quieren llamar a servicios del sistema operativo deben de saber llamar a las DLL’s (o en algunos casos a las COM). Ya verán como este programita que comenzó desde cero poco a poco se va a convertir en un juego de verdad.

junio 14, 2010 Posted by | Uncategorized | , , , , , | 1 comentario

Poor Programmer Reto 1 Episodio 8

–Ahora si a programar desde cero–

La verdad es que eso de hacer videos se me había complicado demasiado, ahora en lugar de hacer episodios aislados como antes voy a hacer grabaciones mas o menos extensas sobre algún proyecto y luego voy a rebanarlas y envolverlas cual si fueran caramelos para distribuirlas de manera continua a lo largo de las semanas. En esta ocasión me puse a escribir el programa correspondiente al reto uno absolutamente desde cero, este código no contiene ni una sola de esas horribles macros ni tan siquiera constantes externas o source code escrito por nadie mas.

Si acaso lo único externo son las llamadas a la API de windows que ya de por si son llamadas creando una sección de importaciones mas o menos RAW. Esta sección de importaciones es sin duda la parte mas interesante de este video.

En si el video no tiene gran valor para los programadores mas avanzados pero al menos este y los 3 episodios que siguen sin duda serán apreciados por quienes apenas se inician en el ASM, ya que en este se dan varios consejos sobre como escribir código en ensamblador que sea legible y sencillo de mantener. Cosa que es indispensable al programar en un leguaje tan cercano a la máquina como lo es este. En esta parte se describen las directivas principales de un programa en ASM para Windows, la manera de llamar funciones de la API del sistema operativo y una breve explicación de lo que son las cadenas ASCII-Z.

Por cierto, en esta serie cometí un pequeño error en la sección de importaciones que luego del tercer episodio se va a resolver. La sección de importaciones ‘.idata’ tiene como argumentos import data readable writeable. Otra interesante diferencia con los videos anteriores es que este es el primero que tiene música de fondo. En realidad solo puse ese fondo musical (que se supone que es de uso libre) para disimular los pertubadores ruidos ambientales que pueden escucharse en todo momento. Bueno, espero que le den buen uso a estos videos y que se recupere un poco la antigua reputación de este blog.

junio 7, 2010 Posted by | Uncategorized | , , , , , | 2 comentarios

Red Social de Programadores de Ensamblador

–Quienes les gusta el ASM ya no estarán solos–

Una vez mas doy mi mas sincero agradecimiento a toda la gente del Tecnológico de Zitácuaro por la conferencia de Gráficas por Computadora a la que me invitaron como expositor. Como recordarán luego de esa conferencia quedaron 2 temas en el aire: El hacer un grupo de maestros que compartan información sobre programación en Ensamblador y otro dedicado al desarrollo de videojuegos en este mismo lenguaje. A dos semanas y desde mi escondite de 8 metros cuadrados en Monterrey he comenzado una pequeña red social en NING. Aún no está terminada pero ya es mas o menos usable. Para visitarla solo den click en la captura de pantalla mostrada a continuación:


fraccion

Y como de costumbre. ¿Que clase de beneficios obtendrá quien entre a esa red social? El primero es el de convivir, comunicarse e intercambiar información y códigos. Pues lo mas importante de una red social es su gente. Sin mencionar que los buenos programadores de Ensamblador son particularmente difíciles de encontrar. Y para que esta gente pueda comunicarse se dan los siguientes servicios:

Chat:

Platica en tiempo real y en grupo con todos los integrantes de la red social, entre los que destacan maestros, programadores independientes, alumnos y cualquiera que tenga algo que compartir. Parece que este chat tiene una función oculta que te permite buscar gente por su edad que aún no se como funciona. Así que si te saca plática alguien con un avatar de oso color café, di no, aléjate y cuéntaselo a quien mas confianza le tengas.

Foros de discusión:

¿Para qué discutir si podemos pelear? Participa en toda clase de discusiones relacionadas con la programación en Ensamblador, Gráficas por Computadora, Desarrollo de Videojuegos y por supuesto no podrían faltar las burlas a otros autodenominados “profesionales de la industria”. Si tienes algo que decir comienza una discusión. Aunque luego no te quejes si no puedes terminarla.

Grupos:

Para no perderse entre tanta información hay grupos interesados en un tema en particular. Ya hay uno para enseñar a los principiantes a programar en ASM y pienso hacer otros mas que se me ocurran. Si tienen alguna buena idea para un grupo no esperen y créenlo ustedes mismos.

Blogs:

Si lo que tienes que decir es demasiado para el chat y los foros de discusión, prueba el Blog. En este cualquiera que tenga la paciencia y las ideas puede escribir. Igual y puedes hasta escribir algún tipo de manual o entrada que valga la pena compartir con la comunidad.

Fotos y Videos:

Se supone que en esta sección van a ir algunos videotutoriales que aún no se me ocurre como hacer. Por favor denle buen uso a esta función y no nada mas suban imagenes del Goatse y videos de las borracheras con sus cuates.

Eventos:

Simples avisos de eventos que pueden ser usados de muchas formas, desde avisar de simples reuniones del grupo hasta dar fechas de exámenes o entrega de proyectos.

Pues que mas hay que decir. Que aunque esa red social fue pensada para los grupos de ensamblador y programación de videojuegos del ITZ cualquiera puede entrar. Leyeron bien. Cualquiera. Así que si tu que lees esto no perteneces al Instituto Tecnológico De Zitácuaro, Michoacán pero te interesa hacer programación gráfica y videojuegos en Lenguaje Ensamblador eres bienvenido.

Solo recuerda que antes de ser una comunidad ( mas ) de desarrollo de videojuegos o gráficas por computadora, se trata de una comunidad de Programación en Ensamblador. Así que si quieres hablar sobre game engines, software de diseño gráfico o, peor aún, cualquier otro lenguaje de programación que no sea Ensamblador (o C si de casualidad me encuentras ebrio o de muy pero muy buen humor) no esperes escapar con la dignidad intacta. Fuera de eso…

¡Bienvenido a la nueva comunidad virtual de Programación en Lenguaje Ensamblador!

 

noviembre 10, 2009 Posted by | Uncategorized | , , , | 13 comentarios

Avenida RAM

–Direccionamiento de la Memoria Para Dummies–

Los ancianos de Estados Unidos tiene una simpática expresión para describir esas conversaciones nostálgicas de los años pasados: “Memory Lane”, lo que se traduciría como “camino de los recuerdos”. Sin embargo, tal término es perfecto para explicarle a un principiante como demonios funciona la memoria de una computadora. Hace muchas notas se dijo que la memoria de una computadora es similar a un enorme array de bytes que es tan grande como la capacidad de la propia memoria. Pero como se supone que ustedes son principiantes voy a explicarlo de una forma mas ‘amigable con el usuario’.

###Poner aqui el dibujo 1###

Este es un dibujo de la Avenida RAM. Se trata de una muy larga carretera con casitas a un lado. Cada casa se identifica por su número que es único e irrepetible. Es decir que no hay 2 o mas casas con el mismo número en esta calle. Dentro de estas simpáticas casitas viven los bytes, como ya saben (y si no lean la nota llamada “Cuantos Bits tiene un Byte” )los bytes pueden almacenar un nu\mero entero ente 0 y 255 porque tienen 8 bits. Como estas casitas son tan pequeñas solo puede vivir un byte en cada una de ellas. Aunque como buenos vecinos, algunos se ponen de acuerdo para trabajar juntos cuando se trata de representar cantidades mas grandes. Aunque esto se verá un poco mas adelante en esta nota. Por ahora hay que dejar claro ese concepto de “Direccionamiento” o “Addressing”

En idioma inglés, la palabra “Address” se traduce como “Domicilio” y la terminación “-ing” singifica el llevar a cabo una acción. Entonces el concepto de “Addressing” se traduce como “La acción de ubicar un domicilio dado” pero como esto es muy largo en idioma español la mayoría de los profesores usan el extraño término de “Direccionamiento”. Este término es sumamente confuso porque puede interpretarse como si la memoria pudiera moverse hacia una dirección en particular. Yo personalmente prefiero usar el término “Posicionamiento” porque da la idea de algo que busca colocarse en un espacio dado. Ahora sigamos con el asunto de la Avenida RAM.

Normalmente a uno no le interesa la casa de otras personas(a menos que seamos ladrones), sino el hecho de saber donde se encuentran para ir a visitarlas. Para llegar al domicilio de alguien necesitamos saber donde vive, por ejemplo la colonia, calle y número. Esta clase de datos normalmente se guardan en una agenda o libreta de direcciones. Una entrada de una de estas agendas puede verse así:

Nombre: Rosa Mesta

Domicilio: #700 de la Avenida Palo Alto

Ahora, dentro de la memoria RAM lo que almacenamos son datos. Y auque la computadora puede manejar números como posiciones de memoria sin ningún problema este no es el caso de los programadores tradicionales. Y al igual que la entrada de la Agenda anterior, tenemos un nombre (de variable) y su “Domicilio”:

Nombre: Salario

Domicilio: #1234 de la Avenida RAM

Entonces, supongamos que queremos llegar a donde está la variable salario. Para llegar ahí recorremos toda la Avenida RAM hasta llegar frente a la casa marcada con el número 1234. Al llegar ahí, quien vive en el número 1234 nos va a dar la información del salario, que en este caso es bastante cercano al mio:

###Poner aqui el dibujo 2

Un error bastante común es confundir el número que representa una localidad de memoria con la cantidad que esta almacena. Esto es como confundir a una persona con su casa. Pero pasa muy a menudo al manejar los famosos PUNTEROS. Para quienes tengan algo de experiencia programando en C/C++ tienen una vaga idea de lo que estoy hablando. De nuevo no me gusta el término puntero porque se presta a ambiguedad en español. En inglés esta palabra es “Pointer” y aunque no se exactamente lo que significa estoy seguro que no tiene nada que ver con cualquiera de las definiciones en español que hasta ahora he encontrado. Pues su significado es marcar una posición de memoria específica y no indicar una dirección a la que hay que moverse. Ahora volvamos con la analogía de la calle y la agenda:

Lo primero que hay que dejar en claro antes de continuar es que en Ensamblador no existe el concepto de “Tipo de datos” el contenido de un registro de CPU o de una localidad de memoria puede significar cualquier cosa porque para la computadora todos son números binarios, así que es posible hacer cosas locas como restar letras, usar cualquier variable como un puntero o revolver diferentes tipos de datos que no tienen nada que ver entre si. De lo único que hay que preocuparse es que los datos tengan el mismo ancho en bits y aún así hay muchas excepciones a esta regla. Ahora sigamos con los punteros.

No se si a ustedes les haya pasado que van a visitar a alguien que no habían visto en años y al tocar a la puerta los recibe un completo desconocido y les dice que la persona que buscan se casó, cambió de sexo, se fue de misionero al tercer mundo, tuvo hijos (en ese orden) y ahora vive feliz con su nueva pareja en un lugar muy lejano. Luego de eso el desconocido nos da la nueva dirección de la persona que ibamos a ver, y ya si luego de haber escuchado todo lo anterior aun queremos visitarle; pues anotamos en la agenda esos datos y vamos al nuevo domicilio.

###Poner aqui el dibujo 3###

Como ya se dijo, lo único que pueden almacenar las celdas de memoria son números; el significado de esos números no le interesa a la computadora; pero si a nosotros. Entonces, del mismo modo que la información que usamos la información dada por el desconocido para ubicar el nuevo domicilio de la persona que queremos encontrar, en programación podemos usar numero contenido en esta celda de memoria para ubicar la siguiente. Por ejemplo, si buscábamos a Rosa Mesta en el #700 de la Avenida RAM pero nos dicen que ahora vive en el #6941 de la misma calle, vamos al domicilio marcado con el #6941 a buscar a Rosa Mesta.

Esto niños, es lo que se conoce como “Puntero” una celda de memoria cuyo contenido se interpreta como la posición de una celda de memoria. Pero como nosotros programamos en Ensamblador tal cosa no es mas que una celda de memoria con un simple número que no se diferencia en nada de las otras miles de millones de celdas en una memoria convencional.

Pues esta nota ya quedó demasiado larga y aún no acabo de subirle todos los dibujos, espero continuarla mas adelante; algunas de las cosas que veremos serán los “memory alignment”, la verdadera razón por la que las posiciones de memoria se deben de escribir en Hexadecimal, el manejo de los registros generales como punteros y detalles importantes de los accesos eficientes a la memoria.

octubre 19, 2009 Posted by | Uncategorized | , , | 1 comentario

Una Parada en el Camino

–Prepárate para lo que viene–

Esta nota pertenece a la serie “Ensamblador desde Cero: La Saga del Completo Principiante”. Quien no la conozca o piense que esta nota carece de sentido, puede hacer click en el respectivo enlace de las barras de la derecha.

El camino ha sido largo y tedioso, aunque tu perspectiva de las computadoras ha cambiado luego de ver cosas como la diferencia entre el gabinete de una computadora y su procesador principal, que los bytes son una unidad de almacenamiento de información y no una unidad de peso como los gramos o que cuando se dice que las computadoras solo entienden ceros y unos se habla en serio. Hasta ahora, y si no te has aburrido de leer tantas letras, ya tienes el conocimiento suficiente como para atreverte a tomar un curso sencillo de programación en un lenguaje mas o menos decente como C.

Pero esto aún no basta para pasar la típica materia de Ensamblador de una carrera de Ingenierías cualquiera, que dicho sea de paso dejan mucho que desear. A partir de aquí verás temas un poco mas complicados pero igual de inúntiles desde el punto de vista de un verdadero programador de Ensamblador. Estos no se abordarán de una manera demasiado profunda ni se programará demasiado, mas bien son conceptos que pueden ser aplicados a cualquier plataforma programable en Ensamblador. Aunque hay 2 puntos importantes a considerar si el motivo por el que estás leyendo este blog es para aprobar una materia de la escuela: ¡La Pesadilla del Zombie Electrónico!

Mas adelante hay una nota sobre este problema pero en resumen, se trata de un gran rezago en la enseñanza del Ensamblador. En la mayoría de las universidades que conozco el Ensamblador que se imparte es para un CPU de Intel fabricado en 1979 y usan todas una antigua copia pirata de un compilador descontinuado en 1994. Normalmente de estos temas no se habla en este blog mas que para hacer burlas y chistes crueles; de hecho, el las nuevas computadoras con Windows Vista tales programas no corren sin el soporte de un emulador. Así que aunque en este curso se hablará primeramente de como trabajan los CPU’s actuales, se harán algunas referencias sobre la historia antigua de estas computadoras. Tengo la esperanza de que si aprenden como funciona una computadora actual, el que puedas entender las antiguas tecnologías será cosa de risa… Para mi.

Fuera de ese asunto, faltan los 2 temas considerados por lo principiantes como los mas difíciles: Instrucciones aritméticas y lógicas y manipulación de la memoria. O como dicen los maestros que quieren asustar niños “Direccionamiento”. Al final de esta serie va a haber (porque hasta hoy octubre del 2009 no los he puesto) algunos códigos típicos que les encargan a los estudiantes como poner al revés una cadena ascii, jugar con algunas llamadas al sistema, dibujar un reloj y si veo que esta serie tiene público puede que hasta les pase el código, archivos y ejecutables completos de un juego sencillo en Ensamblador listo para que se lo entregues a su maestro. De ese modo acabarás todas tus materias, podrás pedir la beca para residencias de mas de 9000 pesos mexicanos, podrás pedir chamba como un respetable administrador de bases de datos y serás un feliz padre (o madre) de familia y te veré comiendo con tus hijos en el parque municipal unas tortillas de harina recién hechas.

O podré arruinarte la vida mostrándose cosas sobre las computadoras que harán de ti un geek ermitaño sin empleo que atacará a otros ‘profesionales de la industria de IT’ de manera instintiva. Aunque esto no lo haré directamente, si se conviertes en asiduo lector de este blog poco a poco tu desprecio por otros ‘desarrolladores’ irá creciendo hasta el nivel en que “les des asco” a otros ‘profesionales de la industria’ por tu actitud hacia ellos. Pero no te preocupes, el asco será mutuo. Pero no hablemos de cosas feas y sigamos con nuestro feliz tour for este alegre y colorido mundo del Ensamblador especialmente pensado para los principiantes.

octubre 15, 2009 Posted by | Uncategorized | , , | Deja un comentario

Ensamblador Desde Cero

–La Saga del Completo Principiante–

¡Bienvenido seas al fascinante mundo de la programación en Lenguaje Ensamblador! Frente a ti se encuentra lo que probablemente será tu primer contacto con el mas antiguo y poderoso de los lenguajes de programación que existen. Esto no es una exageración, pues otro de los nombres con el que es conocido es precisamente como Código Máquina. Y como podrás ver al final de este pequeño serial programar en lenguaje máquina es dificil pero no imposible. Pero eso solo sucederá si eres capaz de llegar al final del mismo.

No se ni me importa que fue lo que te trajo hasta aquí; pero dos son los tipos de personas que terminan en este lugar: Los primeros son simples estudiantes de Ingeniería en computación que en realidad no les interesa programar y solo quieren acreditar una materia para titularse y convertirse en administadores de bases de datos. Los segundos en cambio son aquellos valientes programadores aspirantes a hackers que quieren aprender el verdadero lenguaje de la máquina por el simple placer de hacerlo. Algunos de estos últimos ya tienen idea del enorme poder de este lenguaje y la enorme dificultad que implica dominarlo pero saben que lo necesitan para hacer sus programas. De momento no me importa a cual de estos grupos pertenezcas, igual podrías ser un simple estudiante ahora y tu opinión cambie al ver todo lo que es posible lograr con el Ensamblador. Así que prepárate para lo que vas a ver.

Breve descripción de lo que te espera:

Esta serie trata de explicar los conceptos teóricos mas básicos de la programación en Ensamblador, tales como lo que son los bits, bytes, posiciones de memoria, formatos de numeración binaria y hexadecimal, direccionamiento de la memoria e interfaz básica con el sistema operativo. Así como las herramientas básicas para comenzar a programar, al final deberías ser capaz de hacer un Hola Mundo en Ensamblador sin ningún problema. Por cierto, estas notas no fueron escritas en orden cronológico ni serán las últimas en formar parte de la serie.

Una última cosa: Esta pequeña serie de notas de blog interconectadas están pensadas para aquellos que no tengan grandes conocimientos de computación. De hecho, si esta es tu primera experiencia con la programación será mejor, pues la programación en Ensamblador no se parece nada a la de otros lenguajes mas para ‘humanos’ tales conocimientos solo te estorbarían. Así que si crees que ya sabes programar es mejor que olvides todo lo que has visto hasta ahora, pues todo lo que crees saber de nada te servirá en el camino que estás a punto de recorrer.

>>>>Pasa al siguiente nivel>>>>

***Esta nota pertenece a “La Saga del Completo Principiante”*** Da click en este enlace para pasar a la siguiente entrada de esta serie.

octubre 12, 2009 Posted by | Uncategorized | , , | 6 comentarios

¡Quiero Ver Mas Allá de lo Evidente!

–Crackeando tutorial de Iczelion con OllyDbg–

En esta nota procesaremos el primero de los tutoriales de Iczelion, aunque en realidad vamos a comenzar por el segundo porque la primera parte de lo único que habla es de como funciona el MASM. Y como hay mas gente que habla inglés de la que sabe ensamblador, mejor pasamos a los códigos.

Para esta parte, la mayoría de ustedes ya leyeron la parte teórica, asi que no voy a volver a explicar cosas como para que sirve el .386 (no es la entrada al Modo Protegido) ni lo del modelo flat y stdcall ni los includes ni lo de optioncasemap. Además de que nada de esto nos va a servir. La parte de la sección de datos que tiene 2 cadenas ascii no es la gran cosa y si han seguido este blog desde el principio ya han de saber lo que es una cadena ASCII-Z. Lo único que nos interesa son estas 2 lineas:

invoke MessageBox, NULL,addr MsgBoxText, addr MsgCaption, MB_OK

invoke ExitProcess,NULL

¿Parece sencillo? ¡No lo es! Lo mismo dijeron muchos que intentaron descifrar los tutoriales de Iczelion y ahora viven de hacer querys de SQL. Ese invoke no es una operación de CPU sino una horrible macro, y el primer renglón en realidad se “desenrolla” en 5 instrucciones que en su totalidad miden 18 bytes. Sin contar que a su vez tiene dos llamadas a otra macro anidada llamada ‘addr’ Esta última puede convertirse en 3 o 4 instrucciones mas cada vez que aparece dependiendo de la complejidad de los operandos.

El segundo invoke se desenrolla en solo 2 instrucciones que en total miden solo 7 bytes.

Bueno, los 2 invokes es lo último que ven muchos programadores antes de frustrarse e irse de DBA’s. Pero nosotros tenemos el depurador OllyDbg y al comando de:

OllyDbg, ¡Quiero ver mas allá de lo Evidente!

Obtenemos esta vista del demo de Iczelion en lenguaje máquina:


debug

	00401000 >/$ 6A 00          PUSH 0                                   ; /Style = MB_OK|MB_APPLMODAL
	00401002  |. 68 00304000    PUSH msgbox.00403000                     ; |Title = "Iczelion's tutorial no.2"
	00401007  |. 68 19304000    PUSH msgbox.00403019                     ; |Text = "Win32 Assembly is Great!"
	0040100C  |. 6A 00          PUSH 0                                   ; |hOwner = NULL
	0040100E  |. E8 0D000000    CALL            ; \MessageBoxA
	00401013  |. 6A 00          PUSH 0                                   ; /ExitCode = 0
	00401015  \. E8 00000000    CALL          ; \ExitProcess
	0040101A   .-FF25 00204000  JMP DWORD PTR DS:[<&KERNEL32.ExitProcess>;  kernel32.ExitProcess
	00401020   $-FF25 08204000  JMP DWORD PTR DS:[<&USER32.MessageBoxA>] ;  USER32.MessageBoxA

Como pueden ver, y si no pueden mas abajo lo reescribí en texto para que sea mas sencillo de lamear, las macros se desenrollaron y se convirtieron en instrucciones de ensamblador, las constantes se convirtieron en simples números y además podemos ver las posiciones de memoria del programa.

Para los que ven por primera vez algo como esto, la primera columna indica las posiciones dentro de la memoria virtual, la segunda son los OpCodes en Lenguaje Máquina y la columna que parece código es en realidad código desensamblado. Hasta donde puede, OllyDbg intenta averiguar lo que el programa está haciendo y escribe comentarios en el extremo derecho del código. En este caso, supo que estábamos llamando a MessageBox y Exit Process e incluso identificó plenamente los parámetros. Ahora veamos paso por paso lo que el programa está haciendo:

6A 00 PUSH 0

Aquí están empujando un cero de 32 bits al stack. Esta es la constante MB_OK que le dice a MessageBox el estilo de caja.

68 00304000 PUSH msgbox.00403000

En esta linea están empujando al stack la posición de memoria de la cadena ASCII-Z que dice “Iczelion’s tutorial no.2”. Esta posición es 403000. Pero en el source se usa la etiqueta MsgCaption. La macro addr en este caso no hizo nada porque 403000 es una posición de memoria absoluta. Cuando se usan direcciones relativas como esp + 123h o ebx + edi, addr convierte estas posiciones relativas en absolutas con el uso de la instrucción LEA (esta será motivo de otra entrada)


debug

En esta captura de pantalla se ve el segmento de memoria en ascii y hexadecimal. Si conocen de memoria el código ASCII pueden leer las cadenas directamente. Noten el cero binario con el que terminan y la posición de memoria a la que hacen referencia las funciones que usan texto.

00401007 |. 68 19304000 PUSH msgbox.00403019

Esta linea hace lo mismo que la anterior pero manda al stack la posición de la cadena ascii que dice: “Win32 Assembly is Great!”

0040100C |. 6A 00 PUSH 0 ; |hOwner = NULL

En esta linea se empuja otro cero al stack que le dice a MessageBox que la ventana no tiene padres, pues hOwner indica el handler del Pwner Owner o dueño de la ventana. Este cero indica que aparece en el centro del escritorio. Pero eso ya es cosa de la API de Windows


0040100E |. E8 0D000000 CALL <JMP.&USER32.MessageBoxA> ; \MessageBoxA

Aquí se llama a MessageBoxA. Nótese la A mayúscula que va al final. Para Windows hay diferencias entre funciones ascii y unicode. En este caso llamamos a MessageBox versión ASCII. Otra de las cosas importantes que nos ocultan las macros.

00401013 |. 6A 00 PUSH 0 ; /ExitCode = 0

Esta ya es parte del segundo Invoke, aquí se empuja un cero al stack que es el único parámetro de la función ExitProcess que termina el programa. La constante NULL se transforma en cero, parece que NULL es mas sencillo de leer en un código que el propio cero.

0040101A .-FF25 00204000 JMP DWORD PTR DS:[<&KERNEL32.ExitProcess>; kernel32.ExitProcess

Finalmente se llama a la función API de windows ExitProcess y se termina el programa. La linea que sigue pertenece un sistema de llamado de funciones conocido como JUMP TABLE o trampolín. Que permite que un programa pueda llamar funciones externas y cambiantes sin necesidad de reprogramación. En esta tabla se colocan los verdaderos llamados a función y cuando hacemos un CALL para ejecutar una función API lo que en realidad hacemos es saltar a esta tabla. Este es un mecanismo interesante pero no hay urgencia de verlo porque FASM no lo usa. De hecho, este programa hace exactamente lo mismo que el PEDEMO.ASM que viene en los ejemplos del fasm y en este mismo blog en la nota llamada “¡Al fin un código!”

Hasta ahora, apenas hemos entendido lo que realmente ocurre tras esos inocentes invokes, y ya tienen una idea de lo peligrosas que pueden ser las macros para los principiantes, es mejor que las guarden para cuando tengan artritis y no puedan teclear sus programas los suficientemente rápido. O por lo menos hasta que realmente sepan lo que están haciendo y lo confirmen con el depurador de códigos en la primera oportunidad.

Para recapitular, hoy aprendimos todo esto:

1.- Se necesita un depurador para entender los tutoriales de Iczelion.

2.- Una macro puede desenrollarse en muchísimas instrucciones de Ensamblador

3.- Los argumentos de una función se introducen por el STACK en orden inverso a como quedan dentro del stack frame.

4.- Las constantes como MB_OK, hOwner, etc. Se convierten en simples números enteros casi siempre de 32 bits

5.- La macro ADDR convierte una referencia a memoria de tipo relativa a una posición de memoria absoluta usando la instrucción LEA.

6.- En este caso se usa una JUMP TABLE para hacer las llamadas a la API de Windows, pero FASM no trabaja asi.

Por ahora me regreso a donde estaba, estoy desarrollando una trampa para lamers muy divertida, aunque va a estar lista para la siguiente temporada de caza y esta es hasta el final del otoño. Por ahora traten de leer y analizar los tutoriales de Iczelion ustedes solos a ver que mas se encuentran, recuerden que hay un link a la web de Iczelion a la derecha de este blog.

junio 9, 2009 Posted by | Uncategorized | , , , , , | 15 comentarios

Tutoriales de Iczelion

–El Prometeo del Ensamblador–

Uno de los grandes males de la programación en Ensamblador es la presencia del Zombie Electrónico conocido como 8086. De hecho, en muchas universidades se sigue estudiando este CPU que lleva muerto por lo menos desde 1985. Aún en la era del Pentium, las gráficas 3D y los sistemas operativos multitarea con GUI, se seguía impartiendo el ensamblador de 16 bits, lo que lo desprestigiaba al grado de que aún hoy muchos creen que Ensamblador es sinónimo de programas obsoletos de 16 bits que corrían en pantallas negras con letras grises.

Sin embargo, en cierto momento aparecieron en el Internet unos interesantes tutoriales que demostraban que era posible hacer programas en ensamblador capaces de trabajar en 32 bits. En los noventas, la programación de 32 bits significaba cosas impresionantes como poder manejar 4 gigabytes de memoria en lugar de 64 kilobytes, modos de video con calidad fotográfica mas allá del 320 x 200 a 256 colores, Full Motion Video en lugar de minúsculos sprites y por supuesto modelos con superficies detalladas en los juegos 3D en lugar de esos polígonos con sombreado plano que recordaban cartones de leche. Esos tutoriales mostraban lo básico de la programación en 32 bits para Windows y estaban escritos en MASM. Su autor es un ser cuya identidad hasta ahora se desconoce, pero quien usaba por seudónimo el enigmático nombre de ICZELION.

iczelion original

Poco se sabe de Iczelion, salvo que sacó su seudónimo de un personaje de animación japonesa (lo que sugiere que probablemente sea un otaku) y que opera en Francia. Desde que se dieron a conocer, estos tutoriales han sido traducidos a varios idiomas y variantes de sintaxis de los diferentes ensambladores. Siendo particularmente perturbadora la traducción de un extremista religioso que incluyó en el archivo final textos ofensivos para otras religiones. Aunque lo verdaderamente ofensivo de ese archivo es que no había adaptado ni la mitad del tutorial.

Bueno, la cosa con los tutoriales de Iczelion es que a pesar de haber sido traducidos a los mas diversos lenguajes y sintaxis de los ensambladores, aún son extremadamente difíciles de entender. Sobre todo porque tienen una enorme cantidad de macros y parámetros de compilación que solo funcionan en el MASM. En este blog se intentará una vez mas escribir una adaptación de estos tutoriales. Aunque mas bien es una aproximación.

¿Y cual fue mi experiencia con los tutoriales de Iczelion? La verdad es que topé con piedra, pues no era capaz de hacer funcionar los códigos y cuando milagrosamente lograba hacer que algo funcionara no tenía ni la mas remota idea de lo que había hecho. Fue así hasta que encontré que la única manera de comprender y aprovechar verdaderamente estos tutoriales era usando un Debugger, como el IDA, WDASM o el OllyDbg. De hecho, no es una exageración decir que lanzarse a programar con los tutoriales de izcelion sin recurrir a un depurador de códigos es como tratar de comer nueces sin un cascanueces. Pues los códigos fuentes no te dirán nada con sus macros, constantes y sus directivas de compilación, pero con un depurador puedes ver todo el código en ensamblador puro, las constantes de Windows se convierten en simples números y las macros ‘se desenrrollan’. A partir de aquí, y si medianamente conoces la sintaxis de tu ensamblador (en mi caso fue el FASM), solo queda adaptarlo. Si tienes problemas, simplemente pasa tu propio ejecutable por el depurador y compara el código máquina. Los códigos máquina u OpCodes son los números que aparecen a la izquierda del código desensamblado en la mayoría de los depuradores. Ahora a programar:

Para entenderle a los tutoriales de Iczelion necesitaremos:

0.- Los tutoriales de Iczelion, por supuesto.

1.- Un ensamblador, en este caso el el FASM pero pueden usar cualquier otro si quieren.

2.- Un desensamblador como el OllyDbg, al lado derecho de esta blog pueden hallar un link a este.

3.- Una referencia a la API de Windows. Basta con que diga el nombre de cada función, en que DLL se encuentra y que parámetros recibe. No importa para que lenguaje se halla escrito. Es relativamente sencillo encontrar estas referencias en Internet.

Pasos para procesar los tutoriales de Iczelion:

1.- Lee la documentación que viene sin preocuparte demasiado por el código

2.- Busca el ejecutable de esa sección (el archivo con extensión .EXE) y mételo al depurador de códigos.

3.- El código desensamblado lo copias a un archivo de texto, puedes hacerlo cortando y pegando en el bloc de notas.

4.- Identifica todas las llamadas al sistema, OllyDbg puede hacer esto por ti.

5.- Lleva un registro de todos los símbolos que encuentres, los símbolos son las variables, constantes simbólicas, nombres de estructuras, funciones, etc, etc, etc. Un programador me dijo que un buen programador colecciona todos estos simbolos como si fueran estampitas (cromos, cards o tarjetas de beisbol segun tus creencias).

6.- Para integrar una función de la API de Windows en un programa de FASM recuerda declarar en la sección de importaciones el nombre de la función y el DLL que la contiene. Aquí es donde entra la referencia de la API de Windows.

7.- Al principio puedes usar los números directamente como te los mandó el depurador, pero mas adelante necesitarás declarar esos números como constantes o el código se volverá realmente confuso.

8.-Diviértete…

Por ahora ha sido todo, mas adelante veremos este tutorial con mucho mas detalle, por ahora solo les dejo un enlace a la web de Iczelion a ver hasta donde llegan ustedes solos. Y no se les olvide llevar su depurador porque solo con el código fuente no llegarán muy lejos.

mayo 31, 2009 Posted by | Uncategorized | , , , | 14 comentarios

De Acumuladores, Pilas y Mariachis

Dicen que hubo una vez un niño tan gordo pero tan gordo, que sus padres, en lugar de ponerle nombre de pila le pusieron nombre de acumulador. Esto carece para mi de sentido. Sin embargo, quiero hacer una aclarcación oportuna de términos. Pues así como existe la confusión entre el gabinete y el CPU existe otra confusión entre las unidades de almacenamiento de energía y el stack de una computadora.

Deliberadamente uso el término Stack en inglés. Y eso es porque traducido al español Stack significa “Pila”. Y esta confusión no es propia de las abuelas que no se atreven a acercarse a las laptops de sus nietos, sino de auténticos profesionistas con maestrías y doctorados en computación. Un ejemplo particularmente humillante que vi hace ya tiempo fue el famoso tutorial de la prestigiada Universidad de Guadalajara. Me gustaría pensar que quien hizo esa traducción fué alguna humilde ayudante de secretaria con carrera comercial trunca y no un grupo de reputados colegiados del gremio científico. O ha de ser porque a sus egresados no les exigen saber inglés para graduarse. !En este tutorial se referían al Stack Como Battery!. Así que ya saben, aunque que otra cosa podría esperarse del estado con la mayor cantidad de maquiladoras de computadoras de México.

Otro concepto que se presta a confusión es el de Acumulador. Supe de alguien que en un examen sobre computación, o arquitectura de computadoras como lo llaman los matados, contestó que el acumulador de una computadora era… bueno, no recuerdola respuesta exacta pero prácticamente describió el acumulador de un automovil hasta el último detalle. El registro EAX (o RAX en 64 bits) se llama acumulador porque es el encargado de acumular los resultados de los procesos. Nada tiene que ver con el sistema eléctrico de los automóviles. Para evitar este tipo de confusiones usaré los Términos Stack y EAX.

Otro detalle sobre este famoso tutorial, es que se referían a las variables enteras como “Whole”. Este concepto recuerda mas bien a ‘completo’. El término usado en inglés es Integer. Y es un concepto matemático que no tiene nada que ver con lo ‘completo’.

Bueno, creo que ya insulté demasiado. Y debo aclarar que a esta entrada le borré varios renglones ‘Troll’ en los que me burlaba de un par de lamers que viven ahí mismo. No tengo nada contra la gente de Guadalajara, pues ni los lamers ni los programadores tienen patria, y mas con la capacidad que a ambos les da el internet.

He aqui el link a esta joyita porque la url original que era:

http://udgftp.cencar.udg.mx/ingles/tutor/Assembler.html o la cancelaron o ya no funciona

Para quienes les de flojera leer este enorme texto de 65 kbytes aqui estan los pedazos mas divertidos:

------------------------------------------------------------------------
The registers known by their specific names:

 AX Accumulator
 BX Base register
 CX Counting register
 DX Data register
 DS Data segment register
 ES Extra segment register
 SS Battery segment register
 CS Code segment register
 BP Base pointers register
 SI Source index register
 DI Destiny index register
 SP Battery pointer register
 IP Next instruction pointer register
 F Flag register
-------------------------------------------------------------------------

otra cosa mas, aunque este tutorial es bastante viejo, ya estaba obsoleto desde fines de los ochentas. Espero que si no se han actualizado al menos dejen de hablar del ensamblador para que ya no lo desprestigien. Si alguien de la Universidad de Guadalajara lee esto, le invito a publicar su opini\on en los comentarios.

enero 12, 2009 Posted by | Uncategorized | , , , , , | Deja un comentario