- Para el concepto general, ver ensamblador de alto nivel. Este artículo es acerca de una implementación específica
El High Level Assembly (HLA) es un lenguaje ensamblador desarrollado por Randall Hyde, que puede usar construcciones de lenguaje de alto nivel para ayudar, en el lenguaje ensamblador x86, tanto a programadores principiantes como a desarrolladores avanzados por igual. El HLA soporta, en lenguaje ensamblador, tipos de datos avanzados y programación orientada a objetos. Usa un sintaxis similar a las de varios lenguajes de alto nivel, como C/C++, Ada, Modula-2, y Pascal, para permitir la creación de programas legibles en lenguaje ensamblador, y una transición rápida al HLA de programadores que vienen de los lenguaje de alto nivel.
Orígenes y metas
El HLA fue concebido originalmente como una herramienta para enseñar programación en lenguaje ensamblador a nivel universitario. La idea es aprovechar el conocimiento existente en programación de los estudiantes para que aprendan el lenguaje ensamblador tan rápido como sea posible. La mayoría de los estudiantes que toman un curso de programación en lenguaje ensamblador ya han sido introducidos a las estructuras de control de alto nivel, como IF, WHILE, REPEAT..UNTIL, FOR, etc. El HLA permite que los estudiantes apliquen más temprano en el curso esos conocimientos de programación a la codificación en lenguaje ensamblador, permitiendo que dominen otros temas necesarios de antemano antes de aprender cómo codificar las formas de bajo nivel de estas estructuras del control. "The Art of Assembly Languaje" por Randall Hyde usa el HLA para este mismo propósito (véase los enlaces externos para leer una versión en línea del libro).
Ensamblador de alto y bajo nivel
Una idea falsa común sobre HLA es que no es un "ensamblador de bajo nivel" como los productos MASM de Microsoft o TASM de Borland. Generalmente, la gente desarrolla esta idea falsa después de mirar un típico programa "hola mundo" escrito en el HLA, que consiste en una sola invocación macro para el cuerpo del programa:
program HelloWorld;
#include("stdlib.hhf")
begin HelloWorld;
stdout.put( "Hello World" nl );
end HelloWorld;
Combinado con declaraciones similares a las de Pascal o C, mucha gente tiene la impresión que de ninguna manera el HLA es un lenguaje ensamblador, sino más bien alguna clase de lenguaje de alto nivel. De hecho, la sentencia "stdout.put" en el código de arriba no es nada más que un macro de lenguaje ensamblador que se expande a código como el siguiente:
program HelloWorld;
#include( "stdlib.hhf" )
static
hwString :string := "Hello World" nl;
begin HelloWorld;
// Se pone en la [[pila (informática)|pila]] o ''stack'' la dirección del string "Hello World"
push( hwString );
// LLama una función de la biblioteca estándar del HLA
// que imprimirá el string cuya dirección
// ha sido puesta en la [[pila (informática)|pila]] o ''stack''.
call stdout.puts;
end HelloWorld;
No hay absolutamente nada que detenga a un programador de escribir el programa "hola mundo" en lenguaje ensamblador de bajo nivel, si realmente desea hacer esto (nótese que no existe razón práctica alguna de hacer esto). Sin embargo, para el principiante que está experimentando su primera hora con el lenguaje ensamblador, el código anterior es mucho más accesible que el último, es decir, explicar la pila y cómo los parámetros se pasan a un procedimiento por medio de él es un tema relativamente avanzado.
El HLA soporta todas las instrucciones de máquina de bajo nivel que los otros ensambladores x86 y, de hecho, las estructuras de control de alto nivel del HLA se basan en las que se encuentran en MASM y el TASM, cuyas características de lenguaje de alto nivel precedieron por varios años la llegada del HLA. En el HLA, uno puede escribir código ensamblador de bajo nivel tan fácilmente como con cualquier otro ensamblador, simplemente ignorando las construcciones de control del lenguaje de alto nivel del HLA. Las características como las de lenguaje de alto nivel aparecen en el HLA para proporcionar una ayuda de aprendizaje para los programadores que están comenzando, con la asunción que descontinuarán el uso de esas sentencias una vez dominen el conjunto de instrucciones de bajo nivel. En la práctica, muchos programadores de experiencia continúan usando las sentencias de alto nivel del HLA, MASM, y TASM, mucho después de haber dominado el conjunto de instrucciones de bajo nivel, pero esto usualmente es hecho con propósitos de legibilidad.
Características que lo distinguen
Dos características de HLA lo ponen aparte de otros ensambladores x86: su poderoso sistema de macros (lenguaje en tiempo de compilación) y la biblioteca estándar del HLA.
Sistema de macros
El lenguaje en tiempo de compilación del HLA permite que los programadores extiendan con facilidad el lenguaje del HLA, incluso creando su propio Lenguaje Específico de Dominio para ayudarles a solucionar problemas comunes de programación fácilmente. El macro de stdout.put descrito arriba brevemente es un buen ejemplo de un sofisticado macro que pueda simplificar las vidas de los programadores. Considere la siguiente invocación del macro stdout.put:
stdout.put( "I=", i, " s=", s, " u=", u, " r=", r:10:2, nl );
El macro stdout.put procesa cada uno de los argumentos para determinar su tipo, luego llama al procedimiento adecuado en la biblioteca estándar del HLA para manejar la salida de cada uno de estos operandos. Asumiendo que i es un entero con signo de 32 bits, s una variable de string, u un entero sin signo de 32 bits, y r un valor de punto flotante de 32 bits, el macro de arriba se expande a código como el siguiente:
push( iEqualsStr ); // Se pone en la pila la dirección del string "I="
call stdout.puts; // Imprime "I="
push( i );
call stdout.puti32; // Imprime i como un entero con signo de 32 bits.
push( sEqualsStr ); // Se pone en la pila la dirección del string " s="
call stdout.puts; // Imprime " s="
push( s ); // Se pone en la pila la dirección del string s
call stdout.puts; // y se imprime ese string.
push( uEqualsStr ); // Se pone en la pila la dirección del string " u="
call stdout.puts; // y se imprime ese string.
push( rEqualsStr ); // Se pone en la pila la dirección del string " r="
call stdout.puts; // y se imprime ese string.
push((type [[dword]] r)); // Se pone en la pila el valor del número real r.
pushd( 10 ); // Se pone en la pila el ancho del campo.
pushd( 2 ); // Se pone en la pila el número de posiciones decimales.
call stdout.putr32; // Se imprime el valor como real.
Debe estar claro que el código de una sola línea de más arriba es mucho más fácil de escribir, leer, y mantener que su expansión. Esta es una de las ventajas de usar macros en código de lenguaje ensamblador. Por supuesto, la mayoría de los ensambladores proporcionan algún tipo de capacidad macro, la ventaja que ofrece el HLA sobre otros ensambladores es que es capaz de procesar macro argumentos como "r:10:2" usando las extensas funciones de string en tiempo de compilación, y las facilidades de macros del HLA pueden encontrar los tipos de las variables (como i, u, s, y r), y usar esa información para dirigir la expansión del macro, como fue hecho en este ejemplo.
Biblioteca estándar
La biblioteca estándar del HLA es un conjunto extensivo de rutinas y macros preescritos, como el macro stout.put descrito arriba, que hacen la vida más fácil para los programadores, salvándolos de "reinventar la rueda" cada vez que escriben una nueva aplicación. Quizás tan importante como eso, la biblioteca estándar del HLA permite a los programadores escribir aplicaciones portables que funcionan bajo Windows o Linux con nada más que una recompilación del código de fuente.
Invocación desde la línea de comandos
El sistema de lenguaje del HLA v1.x es una herramienta manejada por línea de comandos que consiste en varios componentes, incluyendo un programa "shell" (por ejemplo hla.exe bajo Windows), el compilador de lenguaje del HLA (por ejemplo., hlaparse.exe), un traductor de bajo nivel (como por ejemplo, MASM, TASM, o FASM bajo Windows o el Gas bajo Linux), un enlazador (link.exe bajo Windows, ld debajo de Linux), y otras herramientas tales como un compilador de recursos bajo Windows.
La aplicación "shell" del HLA procesa parámetros de comandos de línea y dirige los archivos apropiados hacia cada uno de los programas que conforman el sistema HLA. Acepta como entrada archivos ".hla" (archivos fuente HLA), archivos ".asm" (archivos fuente para los ensambladores MASM, TASM, FASM, o Gas), archivos ".obj" (".o") para entrada al enlazador, y archivos "rc" (para el uso por un compilador re recursos).
El HLAPARSE.EXE (solo "hlaparse" bajo de Linux) es el "compilador" que traslada archivos fuente HLA a una forma ".asm" intermedia (muy similar a como el GCC traslada archivos C/C++ a archivos fuente en lenguaje ensamblador). La salida del programa HLAPARSE es traducida a código objeto por MASM, FASM, TASM, o Gas. El código objeto es enlazado en un formato ejecutable por un enlazador. Toda esta actividad es transparente al usuario, el programa "shell" realiza todos estos pasos automáticamente. Aunque usar ensambladores secundarios como el MASM o el Gas para procesar la salida del HLA es algo controversial entre programadores de ensamblador de la "vieja escuela", una gran ventaja ofrecida por este esquema es que es una cuestión trivial traducir código de ensamblador con la sintaxis del HLA a código ensamblador del MASM, TASM, FASM, o Gas. Esto es una muy agradable facilidad para los que necesiten traducir código entre diferentes ensambladores. El HLA es el único ensamblador que proporciona la capacidad de traducir su código a tantas diferentes sintaxis.
Véase también
- High Level Assembler
- Ensamblador
- Lenguaje ensamblador
- Lenguaje ensamblador x86
- Netwide Assembler (NASM)
- flat assembler (FASM)
- RosASM
- High Level Assembly Language (HLA)
- GNU Assembler (Gas)
- Microsoft Macro Assembler (MASM)
- Turbo Assembler (TASM)
- GoASM
- A86 y A386 assemblers
- GNU toolchain
Referencias
Enlaces externos
- Homepage
- The Art of Assembly Language
- The Art of Assembly Language (Texto del libro)