sábado, 1 de agosto de 2015

Ensamblador, una introducción al lenguaje de programación

Lenguaje ensamblador

El lenguaje ensamblador  es un lenguaje de programación de bajo nivel para microprocesadores y microcontroladores.


Lenguaje Ensamblador
Tomado de  mastermagacine

Implementa una representación simbólica del códigos de máquina binario y otras constantes necesarias para programar una arquitectura dada de la CPU y consiste en la representación más directa del código máquina específico para cada arquitectura legible por un programador.
Está basada en  mnemónicos que simbolizan las instrucciones,  registros del procesador, y posiciones de memoria.
El ensamblador realiza una traducción más o menos isomorfa desde las sentencias mnemónicas a las instrucciones y datos de máquina.
Actualmente se utiliza cuando se requiere la manipulación directa del hardware, alto rendimiento, o un uso de recursos controlado y reducido,  controladores de dispositivo  y en el desarrollo de sistemas operativos. 

Características


El lenguaje ensamblador no suele ser portable, en otras palabras, el  código para un microprocesador no sirve para ejecutarse en otro (modelo o marca diferentes) por lo que es necesario modificarlo para  usarlo en otro microprocesador de diferente modelo o arquitectura diferentes. En estos casos el código debe reescribirse.

El lenguaje ensamblador permite controlar exactamente las tareas realizadas por el microprocesador y es capaz de crear código imposible de imitar en un lenguaje de alto nivel, ya que el lenguaje ensamblador dispone de instrucciones que no están disponibles en los lenguajes de alto nivel.

Programas ensambladores


Son programas que traducen desde el lenguaje nemónico ensamblador al código máquina real de ceros y unos que realmente se almacena en la memoria del microprocesador.
No hay que confundirlos con el lenguaje en ensamblador que es un lenguaje sencillo creado para no programar directamente en código máquina. Son programas que permiten escribir directamente los nemónicos y nos evita teclear los códigos correspondientes a cada instrucción.
Han estado disponibles desde los años 1950. Los ensambladores modernos, optimizan la planificación de instrucciones para explotar la CPU de forma eficiente.
Hay dos tipos de lenguaje ensamblador dependiendo de los pasos que pasan a través del código fuente.
•          Los  de un paso pasan a través del código fuente una vez y asumen que todos los símbolos se definirán antes de cualquier instrucción que los refiera.
•          Los de dos pasos crean una tabla con todos los símbolos y sus valores en el primer paso, después en un segundo paso utilizan la tabla para generar el código definitivo. En el primer paso se debe por lo menos poder determinar la longitud de cada instrucción para que se posible calcular las direcciones de los símbolos.
Un lenguaje ensamblador de un solo paso es  más rápido mientras que un  ensamblador de dos pasos permite al programa ser definido de manera más lógica de modo que será más fácil de programar y de leer.
La palabra ensamblador se utiliza para referirse al lenguaje ensamblador y  también al programa ensamblador.

Operaciones


Las instrucciones de la CPU pueden agruparse, según su funcionalidad, en:
Operaciones con enteros: (de 8, 16, 32 y 64 bits dependiendo de la arquitectura de la CPU,
Estas son las operaciones que realiza la ALU (enlace a Arquitectura Básica) de la CPU
•          Operaciones aritméticas.
•          Operaciones booleanas.
•          Operaciones de bits.
•          Comparaciones
Operaciones de movimiento de  datos:
Entre los registros y la memoria:

Aunque la instrucción se llama "mover", en la CPU, "mover datos" significa en realidad copiar datos, desde un origen a un destino, sin que el dato desaparezca del origen.
Se pueden mover valores:
•          desde un registro a otro
•          desde un registro a una dirección de  memoria
•          desde una dirección  de memoria a un registro
•          desde una dirección de memoria  a otra
•          asignar un valor inmediato a un registro
•          asignar un valor inmediato a una dirección de memoria


Operaciones de pila:


La pila es una serie de posiciones de memoria especiales donde los datos se almacenan como en una caja. El primer dato en entrar será el último en ser leído mientras que el último dato en entrar será el primero en ser leído. Por eso se llama pila y su almacenamiento es de tipo LIFO (Last Input, First Output)
•          PUSH escribe datos en la pila.
•          POP lee datos de la pila


Operaciones de entrada/salida:


Son operaciones que mueven datos de un registro o desde la memoria hacia un puerto o viceversa.
•          INPUT Lectura desde un puerto de entrada
•          OUTPUT Escritura hacia un puerto de salida

 

Operaciones para el control del flujo del programa:


Saltos condicionales de acuerdo con el  resultado de operaciones de comparación
Saltos incondicionales
Llamadas y retornos de interrupciones
Llamadas y retornos de subrutinas

Operaciones con números reales:
La ALU de una CPU sólo puede sumar, aun así diferentes secuencias de instrucciones así como la utilización de diferentes códigos y bits de acarreo y signo permiten realizar las operaciones aritméticas básicas y otras más complejas.
Una CPU puede tener operaciones de punto flotante con números reales a través de un coprocesador numérico.


Operaciones matemáticas:



Operaciones aritméticas. Suma, resta, multiplicación, división, cambio de signo, valor absoluto, parte entera

Operaciones trigonométricas. 

Operaciones con logaritmos, potencias y raíces.


Lenguaje máquina


El lenguaje ensamblador utiliza mnemónicos para cada una de las instrucciones de la CPU. Aun así su programación no es sencilla pues es necesario conocer a fondo la arquitectura física del microprocesador para poder programarlo eficientemente.
Por ejemplo, en un lenguaje una sentencia del tipo:
MOVER RB, 45H
Asigna el valor hexadecimal 45 (69 en decimal) al  registro B.

El programa ensamblador lee la sentencia de arriba y produce su equivalente binario en lenguaje de máquina, en este caso es una instrucción de dos palabras, la primera palabra estará codificada en el juego de instrucciones del microprocesador, se trata de una codificación arbitraria en la que la instrucción MOVER RB Hx puede estar codificada como 1F (por ejemplo) y la segunda palabra sería el valor propiamente dicho, en este caso el 45 de modo que tendríamos:
Binario: 00011111 (1F)  010010101 (45)  (hexadecimal: 1F 45)
El mnemónico MOVER (MOV en Inglés) es un código de operación u opcode. Como acabo de indicar el opcode es seguido por la lista de argumentos o parámetros, (en este caso uno) completando la instrucción de ensamblador. En el ejemplo, RB  es un registro de 8 bits del procesador, al cual le asignaremos el valor hexadecimal 45 tal y como se ha  indicado.
Por tanto el código de máquina que genera el ensamblador estará  formado  por 2 bytes. El primero contendrá la instrucción MOVER (codificada arbitrariamente) y el segundo contendrá el valor  introducido 45.
Dicha instrucción binaria 00011111   010010101 será interpretada directamente por el procesador el cual al final del ciclo habrá introducido el valor 01000101 en el registro RB.

Macros

Una macro en ensamblador es una secuencia de instrucciones. Una vez un macro ha sido definido, su nombre puede ser usado en lugar de un mnemónico. Cuando el ensamblador procesa la macro, reemplaza la sentencia por las líneas del texto asociadas a ese macro, entonces las procesa como si hubieran existido en el archivo del código fuente original. Es decir una macro en ensamblador es una subrutina, es decir un programa corto escrito previamente y almacenado en un lugar específico de la memoria el cual es llamado cada vez que se invoca la macro.
Las macros suelen nombrarse con etiquetas cortas que las definen y hacen que los programas en lenguaje ensamblador parezcan mucho más cortos, requiriendo menos líneas de código fuente, igual que en los lenguajes de alto nivel.
Aunque el lenguaje ensamblador es casi siempre manejado y generado por compiladores, todavía se utiliza manipular directamente el hardware, obtener acceso a instrucciones especializadas del procesador, o para resolver problemas de desempeño crítico.

Uso actual


La complejidad de los procesadores actuales hace la optimización cada vez más difícil para los compiladores, además las prestaciones cada vez mayores de los procesadores hacen que la mayoría de las CPU permanezcan desocupadas la mayor parte del tiempo. Esto hace que la velocidad de ejecución de código no sea ya un problema.

El lenguaje ensamblador se utiliza principalmente para traducir lenguajes de alto nivel en código máquina, o para funciones críticas o en procesos industriales, sobre todo si es importante el tiempo real.

También se utiliza si se necesita un ejecutable independiente (stand-alone) que deba ejecutarse sin recursos. Son programas empotrados que solo disponen de una pequeña cantidad de memoria y está dirigido para hacer tareas con propósito simple, por ejemplo en teléfonos, sistemas de ignición de combustible para automóviles, control de aire acondicionado, sensores  y sistemas de seguridad.

O cuando se necesitan utilizar instrucciones específicas del procesador no disponibles por el compilador. Un ejemplo es la instrucción de rotación de bits que se utiliza en algoritmos de cifrado.

El lenguaje ensamblador es todavía enseñado en los programas de ciencias de la computación y en ingeniería electrónica. Aunque pocos programadores trabajan regularmente con el lenguaje directamente, este es muy útil para estudiar conceptos fundamentales, como aritmética binaria, asignación de memoria, procesamiento del stack, procesamiento de interrupciones, y diseño de compiladores.
La mayoría de los computadores modernos tienen un conjunto de instrucciones similares. Con lo que estudiar un solo lenguaje ensamblador es suficiente para aprender.
Lenguajes de nivel medio como C, proveen sintaxis especial para empotrar lenguaje ensamblador en la plataforma hardware.
El lenguaje ensamblador también es valioso para hacer ingeniería inversa, pues muchos programas son distribuidos exclusivamente como código de máquina. El código de máquina es fácil de trasladar hacia lenguaje ensamblador para luego ser examinado en esta forma, aunque sigue siendo muy difícil trasladarlo a un lenguaje de alto nivel. También existen herramientas para hacer esto último de forma automática.


No hay comentarios:

Publicar un comentario