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.
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.
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.
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:
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.
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:
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.
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:
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.)
Los criterios a tener en cuenta a la hora de seleccionar el lenguaje de programación son: