Lenguaje de ensamblaje y lenguajes de alto nivel: cuándo y por qué

1986/12/01 Alegria Loinaz, Iñaki Iturria: Elhuyar aldizkaria

Las computadoras de primera generación se programaban en lenguaje máquina. Las segundas con lenguaje de ensamblaje. El tercero y cuarto se programan en lenguaje de alto nivel. Los de la generación quintana se programarán con un lenguaje cercano al lenguaje natural.

Las computadoras de primera generación se programaban en lenguaje máquina. Las segundas con lenguaje de ensamblaje. El tercero y cuarto se programan en lenguaje de alto nivel. Los de la generación quintana se programarán con un lenguaje cercano al lenguaje natural.

Por tanto, para programar una computadora actual es necesario dominar algún lenguaje de alto nivel (BASIC, FORTRAN, COBOL, PASCAL...) y utilizando este lenguaje como herramienta, redactaremos programas que resuelvan nuestros problemas. En cualquier caso, en una computadora concreta, y más aún en una micro, no podemos utilizar cualquier lenguaje, sino uno de los que nuestra computadora tiene implementados en su Sistema Operativo.

El uso de lenguajes de alto nivel no excluye el lenguaje máquina y sobre todo el lenguaje de ensamblaje (assembler). Estas opciones, al menos la del ensamblaje, a veces son muy adecuadas.

El objetivo de este artículo es explicar cuándo y para qué deben utilizarse el lenguaje de ensamblaje (ASSEMBLER) y los lenguajes superiores.

Introducción

Las órdenes que ejecuta o ejecuta directamente un computador son aquellas escritas en lenguaje máquina. Las órdenes en lenguaje máquina son conocidas y ejecutadas por la Unidad de Control de la CPU. Estas órdenes se adhieren al computador y son relativamente sencillas, cada una de ellas representa una sola operación aritmética o lógica normal. El lenguaje máquina se expresa en códigos binarios mediante 0 y 1.

Programar en binario resulta muy pesado, dejando a un lado las otras molestias. Por ello se crearon lenguajes simbólicos, primero lenguajes de ensamblaje y luego superiores.

Los programas escritos en lenguaje simbólico no pueden ejecutarse directamente. Los programas escritos en lenguaje máquina sólo pueden ejecutarse directamente. El objetivo de los traductores es superar esta objeción.

Un programa traductor toma como dato el programa escrito en lenguaje simbólico y como resultado de su ejecución crea un programa equivalente escrito en lenguaje máquina. Por tanto, el programa que realizamos cuando lo programamos en lenguaje simbólico no se puede ejecutar directamente, ya que antes de ejecutarlo hay que realizar un proceso de traducción.

Figura : Esquema funcional del COMPILADOR.

Por eso decíamos que en una computadora no se puede programar en cualquier lengua, porque para programar en un lenguaje es necesario su despertador. Los programas traductores están escritos en lenguaje máquina y forman parte del Sistema Operativo, es decir, los usuarios no deben programarlos y constituyen una de las principales partes del software auxiliar que incorpora la computadora.

Tipos de traductores

El programa que traduce automáticamente del lenguaje de programación a otro lenguaje que la máquina entiende directamente, el lenguaje máquina, se llama traductor. En los traductores se distinguen diferentes tipos; por otro lado, los ensambladores, para traducir programas de lenguaje ensamblador, y por otro lado, los compiladores y los intérpretes para traducir lenguajes superiores.

Cuando los compiladores traducen un programa, obtienen un programa equivalente en lenguaje máquina (llamado programa de objetos), quedando preparados para ejecutar dicho programa de objetos (ver figura 1).

Por el contrario, los intérpretes no traducen íntegramente el programa fuente, sino que lo leen ordenadamente, lo traducen y lo ejecutan. Por tanto, no corresponden a la 2ª fase independiente (traducción y ejecución), ya que ambas se unifican (ver figura 2).

Para traducir un lenguaje de alto nivel se puede utilizar un compilador o un intérprete. Para los casos de BASIC, PASCAL y otros se suelen ofrecer ambas, compilador e intérprete. Cuando el traductor resulta muy complejo y largo, no es conveniente una implementación interpretativa. Y es que para llevar a cabo el programa, el intérprete tiene que estar todo el tiempo en la momoría, tomando para él una parte demasiado grande. Por tanto, en la mayoría de los lenguajes complejos se utilizan compiladores. Por eso no hay intérpretes para COBOL o FORTRAN, al menos en las computadoras normales.

Cuando hay dos opciones para volver, ¿cuál elegir?, ¿interpretación o compilación?

Antes de responder a esta pregunta hay que analizar las dos principales diferencias que genera su uso:

    Cuando se utiliza un compilador, si un programa está bien, su programa objeto puede ser guardado y no debe ser devuelto en posteriores ejecuciones de dicho programa. Por el contrario, el programa deberá traducirse en todas las ejecuciones utilizando un intérprete.
  1. Cuando un nuevo programa se está desarrollando a través del compilador, para probarlo primero se devolverá el programa completo, después se ejecutarán y se repetirán los pasos previos a la corrección de los errores obtenidos. Si se realiza a través del intérprete, el programa puede cambiar a medida que se ejecuta el programa y probarlo al mismo tiempo, sin perder tiempo en traducir todo el programa.
Figura : Esquema funcional del INTÉRPRETE.

Entonces, para responder a la pregunta anterior, hay que diferenciar dos casos: Para el desarrollo de un nuevo programa, lo ideal es utilizar un intérprete, ya que las pruebas generadas por las correcciones pueden realizarse de forma inmediata. Cuando el programa esté probado y funcione correctamente, es mejor conseguir mediante el compilador un programa de objetos equivalente y utilizar el programa de objetos en todas las ejecuciones posteriores, con lo que el tiempo de ejecución ha sido menor, ya que no es necesario traducir.

Por tanto, cuando hay dos opciones para un lenguaje determinado, lo mejor en la fase de desarrollo es utilizar el intérprete, pero una vez comprobado que el programa está bien. Mediante el compilador se obtendrá un programa de objetos para su utilización en la fase de explotación.

Sin embargo, muchas veces no está disponible ya que el Sistema Operativo sólo ofrece uno. En la mayoría de los micro sólo se ofrece intérprete para el lenguaje BASIC. Los programas que traducen el lenguaje de ensamblaje se denominan machihembradores (ASSEMBLY), aunque sean similares a los compiladores. Los ensambladores, al ser el lenguaje de origen correspondiente el lenguaje de ensamblaje, presentan una característica particular: su traducción es muy rápida al obtener una sola orden de máquina de cada manantial. Por tanto, el proceso de traducción es mucho más sencillo que el de los compiladores.

Características del lenguaje

Al margen de las diferencias intrínsecas que supone el uso de uno u otro tipo de traductores en un determinado lenguaje, cada lenguaje de programación tiene sus propias características que limitan su uso.

En primer lugar, los lenguajes de programación podrían clasificarse en dos tipos: el lenguaje de alto nivel y los lenguajes de ensamblaje se comparan a continuación las características de ambos tipos:

    Mientras el lenguaje de ensamblaje está ligado a la máquina, los lenguajes superiores son universales, es decir, un programa escrito con un lenguaje de alto nivel puede ser utilizado en diferentes computadoras sin cambios o con pocos cambios. Un programa escrito en lenguaje de ensamblaje es válido únicamente para un computador concreto. El lenguaje de ensamblaje está muy relacionado con el lenguaje máquina, por lo que está más lejos del programa que el lenguaje de alto nivel. Por tanto, la construcción de los programas resulta mucho más sencilla con un lenguaje de alto nivel que con un lenguaje de ensamblaje, lo que provocará menos errores o errores utilizando un lenguaje de alto nivel. Cuando lo programamos con lenguaje de ensamblaje sabemos cómo se implementan órdenes y datos en el lenguaje máquina o al menos lo percibimos. Por el contrario, el uso de lenguajes de alto nivel, por su carácter universal, impide utilizar los detalles y ventajas de cada lenguaje máquina. En consecuencia, el programa de objetos obtenido con un lenguaje de ensamblaje para el mismo problema será más rápido y tendrá una deposición de memo menor que la obtenida con un lenguaje superior.
  • Para el manejo de algunos componentes u operaciones especiales de la computadora (principalmente para realizar llamadas al sistema o para obtener o modificar información sometida al sistema) es necesario utilizar el lenguaje de ensamblaje. En este caso es obligatorio el uso del lenguaje de ensamblaje.
1. Tabla.- Medidas de los programas del ejemplo.

Por la misma razón, los programas escritos en lenguaje superior son más comprensibles y legibles que los escritos en lenguaje de ensamblaje.

Las características de los párrafos a) y b) están a favor de la utilización de los lienzos superiores y las de los párrafos c) y d) en contra. En definitiva, el uso de lenguajes de alto nivel genera programas más universales, fáciles, fiables y comprensibles, pero con tiempos de ejecución más lentos y con mayor acogida de memoria.

Algunas de las características mencionadas las analizaremos con un ejemplo. En el ejemplo se presenta un programa que, una vez calculados los primeros mil números primos, se redacta 1000 con tres lenguajes diferentes: el lenguaje de ensamblaje, el FORTRAN y el PASCAL (ver figura 3). En los tres casos se ha seguido el mismo algoritmo y el modo de programación (denominada programación estructurada), implementados en el miniconputador denominado VAX 750.

Rastreando el ejemplo, las órdenes del programa escritas en lenguaje de ensamblaje no se entienden si no se conoce el lenguaje de ensamblaje de la computadora VAX 11. Las otras dos se pueden entender si se conoce FORTAN o PASCAL de cualquier computador.

En el programa escrito con lenguaje de ensamblaje, aunque las órdenes se comprenden una a una, resulta muy difícil comprender en su totalidad y realizar algún cambio. En los otros dos casos, sobre todo en el de PASCAL, la inteligibilidad del programa es mucho mayor.

Con el fin de dar una idea más clara de las características expuestas en el párrafo c) anterior, los ejemplos han traducido y ejecutado los 3 programas obteniendo los resultados que se muestran en la tabla 1.

Analizando la Tabla 1 se observa que utilizando lenguajes de alto nivel se crean programas de mayor acogida y de menor lentitud. Por ello, en este caso, la parte de memo que ocupan las órdenes de los programas escritos en lenguaje de alto nivel es (aproximadamente) un 50% mayor que la parte correspondiente al programa de lenguaje de ensamblaje, llegando al 100% para los datos. De cara al tiempo de ejecución, el programa de lenguaje de ensamblaje es un 50% más rápido que el de FORTRAN y un 100% más rápido que el de PASCAL. Estas medidas son bastante generalizadas, aunque en el caso de la adopción del memori de este ejemplo hay demasiadas diferencias.

En general, se puede afirmar que los programas realizados en lenguaje de alto nivel son un 50% más lentos y altos que los realizados en lenguaje de ensamblaje.

Tras ver y analizar las características anteriores, ha llegado el momento de responder a la pregunta principal. ¿Cuándo utilizar un lenguaje de ensamblaje y cuándo un alto nivel?

La respuesta es ahora evidente. En la mayoría de los casos se utilizarán lenguajes de alto nivel y lenguaje de ensamblaje únicamente en los dos siguientes casos.

    Para la realización de un programa o subprograma que manipule determinados componentes y/o operaciones especiales de la computadora, en cuyo caso es imprescindible el uso del lenguaje de excitación (ver párrafo d)). El tiempo o momento de ejecución sea crítico. Por ejemplo, cuando un programa construido con un lenguaje de alto nivel no entra en la memoria, si se hace con un lenguaje de mangas se puede introducir. En aplicaciones en tiempo real el tiempo de ejecución es crítico, por lo que merece la pena realizar el programa completo o las subrutinas más utilizadas con lenguaje de ensamblaje.
2. Tabla. Lenguajes de programación más importantes.

Sin embargo, cuando utilizamos un lenguaje de alto nivel, ¿qué lenguaje escoger? No es objeto de este artículo responder a esta pregunta, pero para la toma de decisión se tendrán en cuenta las siguientes tres características:

ver tabla 2
    Tipo de aplicación. No es lo mismo programar la política de gestión que la aplicación científica. Mientras que en los primeros se manejan cantidades muy elevadas de datos mediante cálculos simples, en los demás lo más importante y complejo es el cálculo. Por ello, existen lenguajes dirigidos al cálculo científico (FORTRAN, APL...) dirigidos a la gestión (COBOL, RPG,...) aunque otros se utilizan en dos ámbitos (PL/1, BASIC, PASCAL). Eficiencia. Algunos lenguajes, cuando se diseñaron, se centraron en este concepto. En estos casos la mayor importancia es la velocidad de ejecución, la potencia, la eficacia... Por ello, los compiladores resultan bastante grandes y no pueden implementarse en computadoras pequeñas. A este tipo pertenecen los lenguajes COBOL, FORTRAN y PL/1. Actualmente, comercialmente este tipo de lenguajes son los más utilizados.
  1. Metodología. En los últimos años se está dando cada vez más importancia a la metodología en la elaboración de software. En lugar de centrarse en la eficacia, algunos lenguajes están dirigidos a la construcción de programas de buena metodología, es decir, a través de estos lenguajes se pueden elaborar programas más fiables, estructurados, más simples, más variables. Con estos lenguajes se consigue un software más barato, ya que está demostrado que más de la mitad del coste de un programa se basa en pruebas y ensayos. Un lenguaje de este tipo es PASCAL, actualmente el más adecuado para aprender, ya que acostumbra al alumno en la metodología de programación. El lenguaje BASIC, por su parte, no ayuda en absoluto a realizar programas estructurados y los que aprenden como primer lenguaje adquieren muchas malas costumbres.

En la tabla 1 se puede comparar la velocidad correspondiente a un programa de PASCAL y la correspondiente a un programa de FORTRAN. El de PASCAL es un 25% más lento, pero como se puede observar en la Figura 3, el programa de PASCAL se lee mejor que el de FORTRAN. Además, el compilador PASCAL realiza muchas más comprobaciones, por lo que los errores se encuentran antes reduciendo el tiempo de prueba.

Los lenguajes aquí mencionados son convencionales, es decir, imperativos; no se han mencionado los lenguajes funcionales (LISP y similares) y explicativos (PROLOG) que actualmente tienen un gran desarrollo.

Tampoco se han mencionado los lenguajes desarrollados para aplicaciones concretas (estadistica GPSS, simulación SIMULA, etc.)

Conclusiones

Figura : PROGRAMA EJEMPLO.

Los criterios a tener en cuenta a la hora de seleccionar el lenguaje de programación son:

    Si el problema tiene que ver con la arquitectura de la computadora y con el Sistema, la mayoría de las veces es obligatorio el uso del lenguaje de ensamblaje. Si la toma de memo o el tiempo de ejecución es crítico, lo ideal es utilizar el lenguaje de ensamblaje. A excepción de los dos casos anteriores, se utilizará un lenguaje de alto nivel y teniendo en cuenta el tipo de aplicación, habrá que decidir qué concepto le damos más importancia: eficiencia o metodología. Lo ideal sería elegir un lenguaje eficaz que impulse la buena metodología, pero eso no existe en la actualidad. Sin embargo, las últimas versiones de FORTRAN impulsan la metodología y consiguen programas estructurados sin perder efectividad. Si una vez seleccionado el lenguaje existiera compilador e interpretación para traducir los programas, en las pruebas se utilizaría este último y, una vez comprobado su idoneidad, se utilizará el programa objeto para la explotación.