miércoles, 15 de febrero de 2012

Lenguajes de Bajo Nivel

Lenguajes de bajo nivel. ¿ Qué son?


(Imágen tomada de: http://upload.wikimedia.org/wikipedia/commons/thumb/f/f3/Codigo_de_maquina.png/400px-Codigo_de_maquina.png)

En computo integrado, trabajaremos con Assembly, o lenguaje ensamblador para conocer un poco más como funcionan en sí las instrucciones sin muchas abstracciones y debido a que muchos sistemas embebidos lo usan.
(Nota: Hablaré del concepto de sistemas embebidos en algún post más adelante, mientras tanto aquí)

El hecho de ser un lenguaje de alto nivel o de bajo nivel es relativo, ya que anteriormente lenguajes como C eran considerados de alto nivel porque eran más recientes. Entonces esto no significa que uno sea mejor que lo otro, es más, podemos pensar en estos lenguajes basandonos en sus propósitos.

Assembly nos serviría bastante para realizar manipulaciones directas de hardware para optimizar recursos, en cambio uno no usaría esto directamente para crear aplicaciones para reproducir música.

Los códigos de lenguajes de bajo nivel pueden ser convertidos a código máquina sin siquiera usar un compilador, y el código resultante corre directamente en el procesador. Ésto es por lo cual los programas en lenguajes de bajo nivel son más eficientes y corren más rápido con una menor cantidad de recursos, a diferencia de los lenguajes de alto nivel que para hacer lo mismo son más pesados.

Los lenguajes de bajo nivel hacen uso de registros, pilas, y direcciones de memoria para realizar las operaciones necesarias para correr un programa.

Ejemplos:
  • Lenguaje máquina

El lenguaje máquina es el que los microprocesadores ejecutan directamente sin una compilación previa. Es bastante difícil de usar ya que requiere memorizar o buscar códigos de números para realizar alguna funcion en específico, y hoy en día son muy pocos los que lo usan.

Cada procesador tiene su propio set de instrucciones para código máquina, estas instrucciones son patrones de bits que corresponden a diferentes funciones en la máquina de dicho procesador. Es por esto que cada set de instrucciones es específico para cada procesador determinado de la misma arquitectura.

Para correr un programa usando este lenguaje, el CPU utiliza una secuencia de estos patrones de bits(instrucciones). En los procesadores más simples se ejecuta una instrucción después de otra, mientras que en otros más avanzados se ejecutan más de una al mismo tiempo. Igual que en Assembly el flujo del programa puede ser controlado usando funciones como jump para transferir dicho flujo de una instrucción a otra que no este directamente después. Esto se puede hacerse también con una condición (conditional jump)para saber si cambiar el flujo del programa o no dependiendo en dicha condición.

Este es un ejemplo de código máquina que calcula el n-ésimo número de la serie de Fibonacci

8B542408 83FA0077 06B80000 0000C383
FA027706 B8010000 00C353BB 01000000
B9010000 008D0419 83FA0376 078BD98B
C84AEBF1 5BC3
  • Lenguaje Ensamblador(Assembly)
El lenguaje ensamblador es otro de los lenguajes de bajo nivel, usado en computadoras, procesadores controladores y además en circuitos integrados. La sintaxis de este lenguaje es una representación simbólica de código máquina necesarias para programar dependiendo también de la arquitectura del CPU. Entonces, existen diferentes sintaxis específicos para cada arquitectura de computadora física o virtual, ya que en algunos casos es posible emularlas(SPIM es un emulador de MIPS).

Assembler es el encargado de convertir el lenguaje ensamblador en instrucciones de código máquina del CPU dado. Actualmente existen formas de hacer debug a los códigos de ensamblador lo que facilita un poco su entendimiento.

Un programa en lenguaje ensamblador consiste en una serie de instrucciones y meta-instrucciones a los que se les llaman directivas, comentarios y datos. Esto es lo que la computadora traduce en un flujo de instrucciones ejecutables por el procesador.

Lo que un lenguaje de alto nivel realiza con ciclos, condiciones y otras operaciones sencillas de comprender, el lenguaje ensamblador lo hace utilizando movimientos en stack, registros y direcciones de memoria, lo cual hacen un tanto difícil su compresión.
 
Este es un ejemplo de lenguaje ensamblador de un simple Hola Mundo, usando la sintaxis GAS:


 

Alto nivel vs Bajo nivel. Pros y Contras

Como mencioné previamente, no podemos pensar en los lenguajes de bajo nivel y alto nivel como iguales y compararlos basándose en que tan eficientes son para realizar la misma tarea. 

Sus propósitos son diferentes, por lo cual hay que ver que Pros y que Contras tienen en favor de lo que hacen. Para esto hay que pensar que usaremos los lenguajes de alto nivel para desarrollar aplicaciones y programas, y los de bajo nivel para manipular hardware o crear drivers para diferentes tipos de hardware.

Lenguajes Pros Contras
Alto 
Nivel
-Más comprensibles, ya que proveen una mayor abstracción.

-Fácil de escribir y arreglar errores ya que la mayoría de los compiladores son muy eficientes al decirte los errores.

-Una gran cantidad de funciones ya están programadas en alguna librería.

-Portabilidad, en su mayoría pueden ser usados en sistema o arquitectura.

-Se enfoca más en la usabilidad sobre la eficiencia.
-Menor velocidad ya que dejan el trabajo de bajo nivel a la computadora.

-En programas complejos el tiempo de compilación puede ser enorme.

-No es posible manipular hardware directamente.

-Hacen un mayor uso de recursos y por lo tanto ocupan mayor memoria.
Bajo Nivel -Aprovechamiento de recursos ya que tienen acceso directo a ellos.

-Producen código más eficiente.

-Mayor velocidad, al trabajar directamente con los recursos.

-Útil cuando solo un ejecutable binario es necesario.

-Interacción directa con hardware

-Cuenta con algunas acciones que no pueden realizar compiladores de lenguajes de alto nivel.

-Programación de drivers de computadoras.
-Poca portabilidad ya que dependen de la arquitectura de la computadora.

-Abstracción mínima, ya que la sintáxis es más cercana a lenguaje máquina.

-Complejidad. Son difíciles de usar ya que sin el uso de abstracciones es más difícil desarrollar programas complejos.

-El programador necesita entender bien la arquitectura donde esta usándolos.

-Muy tendiente a bugs difíciles de arreglar.

-Por lo mismo de la complejidad, puede ser difícil de dar mantenimiento a software en estos lenguajes.

-Un pequeño cambio en el diseño del programa puede dejar inútil todo lo demás.

Referencias



1 comentario: