Programación en Lenguaje Ensamblador

-El Verdadero Lenguaje de las Máquinas-

Como automatizar el llamado de Funciones en ASM

–Esto es mas util de lo que parece a primera vista–

Esto del juego me está haciendo reconsiderar mis métodos tradicionales de programación. Cuando comencé a programar en ASM para Windows los programas de los que aprendí usaban demasiadas macros y tan solo me limité a programar el mismo código a mano para evitar usarlas, pero ahora me doy cuenta de que hay mejores métodos para hacer este tipo de programción sin meterme para nada con las macros. Una de ellas es la llamada básica de las API.

La manera de llamar a la API de Windows es introducir por el stack en orden inverso los argumentos y luego llamar a la función con un CALL indirecto del tipo CALL [proceso].  La verdad es que aunque hacer esto es la manera mas eficiente tiene muchos inconvenientes. El primero es que es un lio recordar el orden y tipo de los argumentos y que muchos de estos argumentos a su vez pueden ser llamadas a otras funciones. Algunas de ellas tienen tantos argumentos que una simple inicialización puede tomar mas de cien lineas. La idea que tengo para estandarizar este proceso es el siguiente wrapper.

Pero antes de continuar es bueno que sepan lo que es una función wrapper: Un wrapper es una función que a su vez llama a otra. La función que es llamada puede cambiar pero la que llama permanece siempre con el mismo formato. Esto permite hacer modificaciones a nivel interacción con el sistema operativo sin necesidad de cambiar el source code de la aplicación y en este caso para llamar a todas las funciones con tan solo una llamada a función con un solo parámetro, la función se vería mas o menos así:

                          push     [message_box]
                          call       win32api

Por supuesto esta enorme simplificacion no es gratis, pues lo que haría esta función es lo siguiente:

1.- Usaría el único parámetro de entrada como un índice a una table que contiene las entradas de una tabla mas grande que contiene espacios para todos los argumentos de entrada y salida y un entero que indica la cantidad de argumentos de entrada que esa función puede recibir, siendo este el primero de los números.

2.- La función usaría ese número de argumentos para encontrar la posición del último de estos valores y los introduciría al stack desde el último al primero, en caso de que la función no recibiera argumentos el valor de la estructura sería cero y se pasaría directamente al punto tres.

3.- Se llamaría a la función en cuestión, de la manera acostumbrada, aunque es buena idea mejorar la estructura para incluir la identificación de la función dentro de esta.

4.- Al retornar de la función el valor de retorno (normalmente retornado en el acumulador) va en la posición correspondiente de la estructura. Normalmente es un solo valor pero pueden darse casos en los que pueda haber mas de un valor de retorno.

5.- La función wrapper termina de la manera habitual. Regresa el control al llamador.

Por ahora solo me hacen falta resolver el como identificar cada una de las entradas de la estructura índice. Se me ocurre que bastará con definir una lista de constantes del tipo función_uno = dword 1 y pasarle este valor como único argumento a la función. Por otro lado, me quedan dudas sobre como va a hacer el programa para recuperar los datos de manera individual.

Lo interesante de este enfoque es que bien aplicado volvería las llamadas a objetos COM y COM+ tan sencillas desde el punto de vista del ensamblador como cualquer llamada a una función propia del programa. Pues algunas de estas llamadas pueden contener múltiples argumentos tanto de entrada como de salida.

Ahora la única pregunta que me hago es como tener acceso a esos datos de manera sencilla. Puede que si hago una función que reciba el identificador de función y una posición de memoria como argumentos y que descarge en esa posición los valores recibidos. Lo mismo podría hacerse para mandar de un golpe todos los argumentos de entrada de una función cuando la estructura creciera de modo que no se pudiera manejar directamente.

Saben, ahora que lo veo escrito me doy cuenta de que toda la ventaja que se logra al no tener que introducir los argumentos manualmente al stack se pierde tratando de tener acceso a ellos de maneras tan indirectas. De cualquier modo voy a dejar esta entrada por si acaso a alguien se le ocurre hacer algo util con este tipo de estructura. De momente se me ocurre que puede usarse para que un procedimiento pueda determinar una secuencia de procesos y ejecutarlos en un orden determinado de manera automática sin necesidad de hacer códigos llenos de bloques condicionales.

Creo que el que una simple llamada a una función tome casi una pantalla completa de instrucciones puede servir para identificarla mejor a distancia. Por ahora lo que se me ocurre que puede ser la mejor opción es tomar la documentación oficial del Windows y convertir las llamadas de C (o lo que sea que se oculte bajo esa horrorosa notación húngara) a ensamblador en un documento sencillo de leer. Se me ocurre hacer un PDF con el Draw de OpenOffice. De momento solo sacaré las funciones que vaya necesitando y ocasionalmente publicaré información sobre alguna de ellas. Puede que un dia junte suficientes para crear una guia completa que pueda compartir con todos ustedes.

Este asunto fue un giro de 360 grados. Volví a quedar en la misma posición pero pude ver todo lo que tenía alrededor mio y sobre todo ubicar donde estaba parado. Y hablando de ciclos, en las próximas notas voy a hablar de algo muy importante sobre como todo eso que llaman interactividad y eventos se resume a un maldito ciclo infinito con unos cuantos saltos condicionales en el centro. Y en el caso del Windows se estudiará el caso de las funciones GetMessage y PeekMessage y la enorme diferencia que hay entre ellas que es tan grande como la de un juego de mesa basado en turnos y un juego de acción arcade en tiempo real.

 

diciembre 28, 2010 - Posted by | Uncategorized | ,

11 comentarios »

  1. disculpa que diga esto pero el contenido de tu blog es extremadamente ofensivo :)en una perspectiva sick-run-sick-what the fuck! es interesante saber que alguna persona se muestre con entusiasmo de hablar de lenguaje ensamblador, pero mi preguntas es:
    si sabias que el hacer un juego en lenguaje ensamblador requiere de mucho codigo y que a veces no encuentres soporte para tus funciones por complejas que sean x que escribiste de algo que realmente no ivas a culminar? digo no es en mala onda pero carajos si fue el objetivo de tu blog no?, ok aceptas que tal vez no lo termines, estoy de acuerdo pero escribe de otra cosa que tal vez tenga mas productividad y ya dejes en paz cuestiones pasadas o eventos de ese tipo, recordando cosas que son referentes a algo que nunca vas a terminar pues mejor hablar de otro tipo de cosas que realmente creas tu q eres capaz de hacer, no es mi intencion molestarte pero si es muy incomodo hablar de lenguaje sin escribir nada serio, sin malos rollos hasta luego.

    Comentarios por Francisca anopel udote medallas | diciembre 30, 2010 | Responder

    • Extranaba esta clase de comentarios tan refrescantes. De hecho tengo que aceptar que he empezado muchas cosas que no he terminado nunca. Esto es debido a que yo mismo soy «extremadamente ofensivo :)». En realidad el objetivo del blog si es hablar sobre ensamblador pero no quiero que sea del modo acartonado que se ve en los libros de las escuelas. Digamos que la idea es mostrar el ensamblador «en accion» y no solo limitarse a hablar de lo mismo que pueden encontrar en cualquier manual de Intel o en libros de ensamblador como el de Barry Brey. Otra cosa por la que dejo algunas cosas sin terminar es porque a la mitad de la investigacion encuentro alguna manera mucho mejor de hacer las cosas y no porque no fuera capaz de cumplir el primer objetivo, eso es parte de ser programador.

      Otra cosa que me gustaria saber es sobre que puedo escribir que tenga «mas productividad» porque siempre es hacerse de algo mas que recursos. Ahora que si consideras que mis escritos donde ataco a «la industria» pues espera a leer una serie de notas que estoy preparando sobre un asunto que voy a «desenmascarar» en las proximas fechas. Y si eso es lo que llamas «cuestiones pasadas» menos que nunca pienso dejarlas pasar y menos ahora que estoy en la posicion perfecta para aplicar en contra-ataque definitivo. Si no es eso, entonces tienes razon con eso de que tengo que escribir mas notas sobre verdadera programacion como cierto amigo de la peninsula iberica me recuerda de cuando en cuando y cuyos consejos pienso tomar muy en serio.

      Comentarios por asm86 | diciembre 30, 2010 | Responder

  2. Hola!! Primero de todo felicitarte por la web… una lástima haberla encontrado ahora, porque llevo varios años queriendo aprender ensamblador y justo ahora ando un poco liado. De todas formas tengo un par de dudas, a ver si me puedes aclarar algo.
    1º Tienes una entrada en la que haces mención de ¿32 ó 64 bits? Pues lo siento pero sigo con la duda… ¿una aplicación programada enteramente para un windows de 32 bits podría ser ejecutada en un sistema de 64 sin ninguna complicación? quiero decir sin necesidad de ponerlo con «compatible con WindowsXP» ni nada así.
    2º Normalmente trabajo con Debian y el Win7 lo tengo solo en el ordenador de la novia. ¿Podría usar el FASM o algún otro Compilador + IDE en linux pero orientado a programar para Windows? Sinceramente, no me apetece tener que instalarme un Win…
    Muchas gracias por adelantado!!
    Sigue con el blog!!!

    Comentarios por Carlos | enero 4, 2011 | Responder

    • Que tal, para la primera pregunta si 32 o 64 bits de momento los sistemas van a trabajar en modo de compatibilidad de modo que los sistemas de 64 bits van a poder ejecutar aplicaciones de 32 bits tal y como en los noventas los procesadores de 32 bits podian ejecutar las de 16 en modo de compatibilidad. Aunque hay instrucciones como CPUID que permiten a un programa saber sobre que tipo de CPU esta siendo ejecutado y asi seleccionar las mejores rutinas para ese procesador en particular.
      En cuanto a la segunda, Existe una version de FASM compatible con linux (y otra hasta de UNIX) x86. Incluso los mismos codigos pueden ser ensamblados sin importar sobre cual de las versiones se procesen, es decir que puedes ensamblar un codigo de Windows en un sistema linux y luego ver como funciona usando WINE. Todas las versiones de FASM las puedes descargar en flatassembler.net.

      Comentarios por asm86 | enero 5, 2011 | Responder

  3. Hola, yo he sido un seguidor medianamente frecuente de este blog(mas por los chismes y chistes malos que por otra cosa), siempre he querido escribir alguna nota de comentario pero no me había arriesgado, la verdad hoy si tengo ganas, hay muchas cosas que me gustaría comentar como tu extraño odio hacia otras personas llamándolos lamers(odio esa palabra), es cierto que hay personas que trabajan y que son supremamente pedantes con lo poco que saben, a esos ignorémosles, pero sabes, muchos otros no tienen esa mentalidad, incluso aquellos que trabajan en áreas a las cuales, por lo que veo, no le tienes respeto, como bases de datos y demás adornos, yo no entiendo esa actitud, el conocimiento no debería ser una vergüenza ni un pecado, NUNCA, vergonzoso es aquel que no comparte teniendo el conocimiento para hacerlo, así sea alguien que apenas este aprendiendo, incluso esa actitud tuya es la más pedante que he llegado a conocer en este sector, si, sueno bastante regañón, pero la verdad así sea desde el que programa en ensamblador y hace mil maravillas, hasta el personaje que solo maneja una base de datos tiene su merito, el conocimiento no es un lujo, y algo que si te recalco es que incluso aquellos que llamas lamers tal vez tengan más merito que tu, ya que tal vez, por lo menos terminan su trabajo, y es que ahí es donde fallas, porque hablas y hablas mucho, pero no veo tus resultados, no veo reflejado lo que sabes en algún proyecto terminado, un código fuente que sirva publicado, etc. Y viendo tus entradas de blog, me doy cuenta, “DE QUE NO ERES PRODUCTIVO”, todo lo veo a medias, ¿Qué paso con programador pobre o programador desde cero?, discúlpame pero mi intensión no es ofenderte pero eso es lo que se llama ser mediocre, pero es para que espabiles y aporte más de lo que sabes, por ejemplo utiliza tus conocimientos y crea videotutoriales que enseñen ensamblador desde cero, así aquellos que no sabemos podamos empezar y colaborar entre nosotros, te aseguro que si lo haces yo seré el primero que llegue y me siente en el pupitre de adelante, metafóricamente hablando. Yo no te voy a decir que me gusta tu blog como hace más de uno, más bien te digo que utilices esta gran herramienta y aportes algo de verdad, no solo uno que otro artículo que realmente aporta algo al conocimiento(Aunque debo admitir que me divertí leyendo los mercenarios digitales). Sería de agradecer que hicieras esos videovideotutoriales (pero desde cero), eso sí que sería un gran aporte y una forma de descargar todo lo que al parecer sabes. Por ejemplo un compatriota tuyo (parece mexicano por su acento) llamado egher y que tal vez conozcas ha hecho unos buenos videotutoriales, tiene sus fallitos, su aporte es algo de agradecer. En pocas palabras, no seas tan creído con lo que sabes y más bien abre paso a algo de humildad. Paz.

    Comentarios por hammer | enero 4, 2011 | Responder

    • TL;DR
      Interesantes tus reflexiones, tienes razon en esa parte de que tengo muchos proyectos sin terminar y no es esta la primera vez que me lo dicen. Por lo menos ya hay proyectos empezados y no como hasta hace poco que ni siquiera los comenzaba. Creo que uno de mis propositos para este 2011 va a ser terminar alguno de esos proyectos. Ahora hablemos un poco sobre orgullo:

      Una accion puede ser motivo de orgullo o de verguenza dependiendo de quien la lleve a cabo. Programar en ASM me ha vuelto demasiado orgulloso por el reto que hay en ello. Una persona «honesta y trabajadora» que administra una base de datos a cambio de un salario pone todo su esfuerzo en ello y si por el fuera buscaria aprender un poco mas para seguir adelante. Ahora bien, para mi (como para muchisimos otros programadores) no seria gran problema ganarme la vida honradamente en uno de esos empleos. Y ese es el problema, HAY DEMASIADOS PROGRAMADORES EN ESOS NIVELES. ¿Sabias que la vida util de un ingeniero informatico es de solo 10 años? Las tecnologias computacionales envejecen rapido y la experiencia en una tecnologia que ha pasado de moda no compensa el salario de un ingeniero veterano sin importar cuantas certificaciones tenga. Resulta mas redituable contratar a un recien egresado con una certificacion en una tecnologia reciente, echarlo a la calle cuando aparezca una nueva y repetir el proceso. Por contra, el ensamblador es intemporal. Un programador de ASM no es el empleado sacrificable que encuentras ayudando en la contabilidad de cualquier empresa sino el maniatico al que recurres unica y exclusivamente cuando todos tus otros profesionales han fallado miserablemente.

      Por lo del «pero desde cero» deduzco que no sabes mucho sobre ensamblador, incluso puede que no tengas mucha experiencia como profesionista de las computadoras y te has dejado impresionar por alguno de ellos. Creeme, si realmente te interesa la programacion en ASM y le dedicas unas cuantas decadas de tu vida va a llegar un momento en que tambien vas a sentir desprecio (que no es lo mismo que odio) por gente que recibe un salario por usar programas cuando deberia crearlos. O bien puedes buscar cualquier otro trabajo de tecnologia donde siempre va a haber un monton de gente mas joven y capaz que tu dispuesta a hacer ese mismo trabajo por menos dinero. Puede que solo hable por mi mala experiencia pero es mejor estar prevenido. Por lo de los ‘videovideotutoriales’ creo que ya eran lo bastante sencillos, aunque puede que para los mas principiantes no lo sean tanto, en cuanto vuelva a hacer videos voy a tomar eso en cuenta, ya par terminar, creo que tengo que poner en practica aquello de que la mejor manera de aprender a ser humilde es desafiar a enemigos que sean mucho mas poderosos que uno y eso en mi caso signifca darle mas duro a la programacion en ensamblador.

      Comentarios por asm86 | enero 5, 2011 | Responder

      • Too long?, ok, no soy un principiante, llevo mi tiempo en esto, soy un amante de C++ y C#, lenguajes que me imagino no te gusta ver ni en pintura, yo he usado ensamblador, pero únicamente con microcontroladores, hace ya unos 7 años aproximadamente, recuerdo que lo último que intente hacer fue crear un Pong para jugarlo en mi TV, pero por falta de dinero y de algunos componentes no pude hacerlo y lo deje a medias, no luche por ello, y eso me frustro ¿sabes?, por eso vi mi reflejo en ti, porque no acabas lo que empiezas. Ahora quiero retomar ese conocimiento. Humm, ese desde cero no es precisamente por mí, es para todo aquel que le nazca aprender, es bastante complicado que la gente entienda que uno no siempre habla por uno mismo (¿será por el egoísmo generalizado?).

        En cuanto a lo que comentas de los programadores en general, no es de sentir desprecio, sino más bien lastima, el mismo blog que usas, lo ayudo a crear uno de esos ¿profesionales? de bases de datos. No me dejo abrumar por aquellos que “saben más”, más bien los veo como objetivo a alcanzar y superar (no como enemigos).

        Respóndeme algo para finalizar esto, ¿Qué ventajas tendría yo realizar un programa(un videojuego tal vez) en ensamblador , además de su veloz ejecución y de poder decir “Yo sé más que los demás, hice un juego en ensamblador y me creo dios”, no ahora en serio, que ventajas trae consigo?.Gracias y paz.

        Comentarios por hammer | enero 5, 2011

  4. y ke grandes proyectos has logrado tu con c++ y C# ?? cres que son mejores que el ensamblador?
    y un pong?? de 16 bit supongo.. esos ya huelen a muerto..(dicho por mario) jaja intenta crear uno de 64 bit!
    y.. pues imaginate un GTA 4 en ensamblador! crees que necesitarias un quad core y un acelerador de los mas caros..?? o un windows 7 en ensamblador? casi cualquier maquina lo levantaria!
    o en la creacion de renders.. te imaginas el tiempo que te ahorrarias..

    Comentarios por Pavon | enero 5, 2011 | Responder

    • Amigo, ¿cuando he hablado yo de la superioridad de una u otra herramienta?, no soy principiante, pero eso no quiere decir que sea el súper sabio, es mas considero que me falta mucho, mucho, muchísimo en este no largo camino, si no infinito. No tengo proyectos hechos, pero que me he puesto una meta de hacerlo si, y yo soy de los que termino algo. El pong tengo el merito de haberlo intentado(aunque no recuerdo absolutamente nada las instrucciones de los microcontroladores), no como otros que ni lo intentan.

      Esto es solo un jalón de orejas para Mario, para que deje tanta palabrería, y nos deleite con algo tangible, muestre imágenes, o algo medianamente usable, porque no es sencillo encontrar, por ejemplo, juegos hechos en ensamblador(o soy muy lento para buscar, una de dos).Es por eso que quiero ver lo que realmente es capaz (lastimosamente no conozco a nadie que sepa lo que al parecer él sabe) y encontrar un objetivo a alcanzar, tal vez hasta le llame maestro ;).

      Comentarios por hammer | enero 5, 2011 | Responder

      • bueno.. pero el ensamblador es mucha mucha teoria.. sobre como funciona verdaderamente la computadora con todos los detalles.. y crees que eso se pueda aprender desde un video? para que reescribir todos los libros siendo que bien uno puede buscar esa informacion ? y si dises que no sos principiante como yo, me puedes decir.. tu sabes las funciones de los opcodes? de 32? o quizas 64?? estas como para programar un hola mundo? entiendes los que programas?? paz =)

        Comentarios por Pavon | enero 5, 2011

  5. Esto ya se convirtió en foro(disculpa mario, no fue esa la intención), amigo, por si no has leído, no programo en ensamblador (tengo muchas ganas y entusiasmo de aprender, porque es realmente fascinante), parece ser que no has entendido el mensaje que le quiero dar a Mario, en fin, mis disculpas.

    Comentarios por hammer | enero 5, 2011 | Responder


Deja un comentario