INTRODUCCIÓN A LENGUAJE ENSAMBLADOR


Importancia De La Programación en Lenguaje Ensamblador
Lenguaje Ensamblador
Es un tipo de lenguaje de bajo nivel utilizado para escribir programas informáticos, y constituye la representación más directa del código máquina específico para cada arquitectura de microprocesador.
*Es un lenguaje de programación de bajo nivel. Consiste en un conjunto de mnemónicos que representan instrucciones básicas para los computadores, microprocesadores, microcontroladores y otros circuitos integrados programables.   
   
La traducción de los nemónicos a código máquina entendible por el microcontrolador la lleva a cabo un programa ensamblador.
El programa escrito en lenguaje ensamblador se denomina código fuente (*.asm).
El programa ensamblador proporciona a partir de este fichero el correspondiente código máquina, que suele tener la extensión *.hex.
1.1   Importancia de la Programación en Lenguaje Ensamblador
·        Su importancia radica principalmente en que se trabaja directamente con el microprocesador; por lo cual se debe de conocer el funcionamiento interno de este.
·        Tiene la ventaja de que en él se puede realizar cualquier tipo de programas que en los lenguajes de alto nivel no lo pueden realizar.
·        Los programas en ensamblador ocupan menos espacio en memoria.

Es importante porque nos proporciona las herramientas para interactuar con el hardware.
Permite la creación de programas muy rápidos y pequeños, y una optimización y un control que no se consigue con lenguajes de medio y alto nivel.
Ventajas
1.      Velocidad: Como trabaja directamente con el microprocesador al ejecutar un programa, la computadora lo procesa más rápido.
2.      Eficiencia de tamaño: Un programa en ensamblador no ocupa mucho espacio en memoria.
3.      Flexibilidad: Es flexible porque todo lo que puede hacerse con una máquina, puede hacerse en el lenguaje ensamblador de esta máquina. Puede hacer tareas específicas que en un lenguaje de alto nivel no se pueden llevar acabo porque tienen ciertas limitantes que no se lo permite.

Desventajas
1.      Tiempo de programación: Como es un lenguaje de bajo nivel requiere más instrucciones para realizar el mismo proceso, en comparación con un lenguaje de alto nivel. Por otro lado, requiere de más cuidado por parte del programador, pues es propenso a que los errores de lógica se reflejen más fuertemente en la ejecución.
2.      Programas fuente grandes: Por las mismas razones que aumenta el tiempo, crecen los programas fuentes; simplemente requerimos más instrucciones primitivas para describir procesos equivalentes. Esto es una desventaja porque dificulta el mantenimiento de los programas, y nuevamente reduce la productividad de los programadores.
3.      Peligro de afectar recursos inesperadamente: Con todo error que podamos cometer, o todo riesgo que podamos tener, podemos afectar los recursos de la máquina.

Lo más común que pueda pasar es que la máquina se bloquee o se reinicialice, porque con este lenguaje es perfectamente posible (y sencillo) realizar secuencias de instrucciones inválidas, que normalmente no aparecen al usar un lenguaje de alto nivel.
4.      Falta de portabilidad: Porque para cada máquina existe un lenguaje ensamblador; por ello, evidentemente no es una selección apropiada de lenguaje cuando deseamos codificar en una máquina y luego llevar los programas a otros sistemas operativos o modelos de computadoras.

El procesador y sus registros internos
Un registro es una memoria de alta velocidad y poca capacidad, integrada en el microprocesador. Permite guardar transitoriamente y acceder a valores muy usados, generalmente en operaciones matemáticas.

Su función es la de almacenar datos, siendo la manera más rápida de hacerlo por el sistema. Los registros se miden en número de bits que almacenan. La CPU, en cambio, comparte un conjunto de localidades de almacenamiento temporal de datos de alta velocidad, denominada con el mismo nombre: registro.
  

Los registros se dividen en 6 categorías:
*Registros de segmento.
*Registros de propósito general.
*Registros de apuntadores.
*Registros de banderas.
*Registros de puntero de instrucción
*Registros de pila.

Algunos ejemplos básicos de registros son:
*Contador de programa (PC).
*Registro de direcciones de la memoria (MAR).
*Registro de datos (RD).
*Registro de instrucciones (IR).
*Palabra de estado de programa (PSW).

 

La memoria principal (RAM)

La memoria principal o primaria, "Memoria Central ", es aquella memoria de un ordenador, donde se almacenan temporalmente tanto los datos como los programas que la CPU está procesando o va a procesar en un determinado momento. Por ejemplo, cuando la CPU tiene que ejecutar un programa, primero lo coloca en la memoria y después lo empieza a ejecutar.

Otros andarán más rápido si el sistema cuenta con más memoria RAM. La memoria Caché: dentro de la memoria RAM existe una clase de memoria denominada Memoria Caché que tiene la característica de ser más rápida que las otras, permitiendo que el intercambio de información entre el procesador y la memoria principal sea a mayor velocidad.

Está formada por bloques de circuitos integrados o chips capaces de almacenar, retener o "memorizar" información digital, es decir, valores binarios; a dichos bloques tiene acceso el microprocesador de la computadora. La MP se comunica con el microprocesador de la CPU mediante el bus de direcciones.

El ancho de este bus determina la capacidad que posea el microprocesador para el direccionamiento de direcciones en memoria. En algunas oportunidades suele llamarse "memoria interna" a la MP, porque a diferencia de los dispositivos de memoria secundaria, la MP no puede extraerse tan fácilmente por usuarios no técnicos.

La MP es el núcleo del sub-sistema de memoria de una computadora, y posee una menor capacidad de almacenamiento que la memoria secundaria, pero una velocidad millones de veces superior. Si tienes más memoria almacenas más datos.


Características de la Memoria

Las magnitudes importantes que caracterizan la Memoria Central o Principal son:

·                     Capacidad o tamaño de esta. Es decir, el número de miles de posiciones que contiene. Normalmente se expresan en K.palabras, aunque en los ordenadores personales al ser las palabras de 8 bits se expresan en K-bytes. En la actualidad, el tamaño de la palabra es múltiplo del byte, ya que de esta forma el acceso a la misma puede hacerse desde uno al ancho máximo del bus de datos, ahorrando en muchos casos tiempo. Así tendremos palabras de 8, 16, 32, 64 bits y capacidades de siempre medidas en potencia de dos: 8, 16, 64, 128 K...etc(siendo 1K igual a 1025).
·                     Tiempo de Acceso. Es el tiempo que invierte el ordenador desde que se emite la orden de lectura-escritura, hasta que finaliza la misma. Este tiempo es muy pequeño, y de él depende la potencia del ordenado. Son típicos tiempos del orden de microsegundos e incluso del orden de 2 a 10 nanosegundos.
·                     El tamaño de la celda define su anchura de palabra, y viene fijado por el ancho del registro de información de memoria. Si la palabra interna es superior a la de la memoria, necesitara hacer más de un acceso para conseguir toda la información.

Concepto de interrupciones

INTERRUPCIÓN
Una interrupción consiste en un mecanismo que provoca la alteración del orden lógico de ejecución de instrucciones como respuesta a un evento externo, generado por el hardware de entrada/salida en forma asincrónica al programa que está siendo ejecutado.
Procesamiento de una interrupción
·         Terminar la ejecución de la instrucción máquina en curso.
·         Salvar el estado del procesador (valores de registros y flags) y el valor del contador de programa, IP, en la pila, de manera que, en la CPU, al terminar el proceso de interrupción, pueda seguir ejecutando el programa a partir de la última instrucción.
·         La CPU salta a la dirección donde está almacenada la rutina de servicio de interrupción (Interrupt Service Routine, o abreviado ISR) y ejecuta esa rutina que tiene como objetivo atender al dispositivo que generó la interrupción.
·         Una vez que la rutina de la interrupción termina, el procesador restaura el estado que había guardado en la pila en el paso 2 y retorna al programa que se estaba usando anteriormente.
Tipos de interrupciones
1.     Interrupciones de hardware. Estas son asíncronas a la ejecución del procesador, es decir, se pueden producir en cualquier momento independientemente de lo que esté haciendo el CPU en ese momento
2.    Excepciones. Son aquellas que se producen de forma síncrona a la ejecución del procesador. Normalmente son causadas al realizarse operaciones no permitidas tales como la división entre 0, el desbordamiento, el acceso a una posición de memoria no permitida, etc.
3.    Interrupciones por software. Son aquellas generadas por un programa en ejecución. Para generarlas, existen distintas instrucciones en el código máquina que permiten al programador producir una interrupción
Sistemas de prioridad
El sistema operativo necesita un mecanismo para priorizar las interrupciones y tratar primero las más urgentes. Para ello, existen varias alternativas:
·         Interrupciones simultáneas: No tienen por qué ocurrir de manera simultánea, sino que se refiere a que en un momento dado puede haber varias interrupciones activas.
·         Interrupciones anidadas: Mientras se está procesando una determinada rutina de servicio de interrupción sucede otra señal de interrupción.
·         Inhibición de interrupciones: Se deshabilitan las demás interrupciones mientras se está tratando una.
Determinación de la fuente que genera la interrupción
Hay distintas formas de identificar la fuente de una determinada interrupción.
·         Polling: el microprocesador comprueba de manera sistemática todos los dispositivos de manera que «busca» cuál de ellos fue el que solicitó la interrupción.
·         Interrupciones vectorizadas: Como ventajas podemos destacar que suele ser rápido, pero implica un alto costo en el hardware.
·         Hardware paralelo: se utiliza un registro de interrupción cuyos bits se controlan de forma independiente por las señales de petición de interrupción de cada periférico. Según la posición de cada bit en el registro, se establece la prioridad.

LLAMADAS A SERVICIOS DEL SISTEMA
Una llamada al sistema es un método o función que puede invocar un proceso para solicitar un cierto servicio al sistema operativo. Dado que el acceso a ciertos recursos del sistema requiere la ejecución de código en modo privilegiado, el sistema operativo ofrece un conjunto de métodos o funciones que el programa puede emplear para acceder a dichos recursos. En otras palabras, el sistema operativo actúa como intermediario, ofreciendo una interfaz de programación (API) que el programa puede usar en cualquier momento para solicitar recursos gestionados por el sistema operativo.

Algunos ejemplos de llamadas al sistema son las siguientes:
·         Time: que permite obtener la fecha y hora del sistema.
·         Write: que se emplea para escribir un dato en un cierto dispositivo de salida, tales como una pantalla o un disco magnético.
·         Read: que es usada para leer de un dispositivo de entrada, tales como un teclado o un disco magnético
·         Open: que es usada para obtener un descriptor de un fichero del sistema, ese fichero suele pasarse a write.

MODOS DE DIRECCIONAMIENTO
Los modos de direccionamiento son las diferentes maneras de especificar un operando dentro de una instrucción en lenguaje ensamblador. Un modo de direccionamiento especifica la forma de calcular la dirección de memoria efectiva de un operando mediante el uso de la información contenida en registros y/o constantes, contenida dentro de una instrucción de la máquina o en otra parte.
Tipos de direccionamiento
Registro:
Sirve para especificar operandos que están en registros.
Implícito: 
En este modo de direccionamiento no es necesario poner ninguna dirección de forma explícita, ya que en el propio código de operación se conoce la dirección de el/los operandos/s al (a los) que se desea acceder o con el/los que se quiere operar.
Inmediato: 
En la instrucción está incluido directamente el operando.
En este modo el operando es especificado en la instrucción misma. En otras palabras, una instrucción de modo inmediato tiene un campo de operando en vez de un campo de dirección. El campo del operando contiene el operando actual que se debe utilizar en conjunto con la operación especificada en la instrucción. Las instrucciones de modo inmediato son útiles para inicializar los registros en un valor constante.
Cuando el campo de dirección especifica un registro del procesador, la instrucción se dice que está en el modo de registro. Su valor es fijo, por lo que se suele utilizar en operaciones aritméticas o para definir constantes y variables. Como ventaja, no se requiere acceso adicional a memoria para obtener el dato, pero el tamaño del operando está limitado por el tamaño del campo de direccionamiento.
Las desventajas principales son que el valor del dato es constante y el rango de valores que se pueden representar está limitado por el tamaño de este operando.
Indirecto:
El campo de operando contiene una dirección de memoria, en la que se encuentra la dirección efectiva del operando.
Si hace referencia a un registro de la máquina, la dirección de memoria (dirección efectiva) que contiene el dato estará en este registro y hablaremos de direccionamiento indirecto a registro; si hace referencia a una posición de memoria, la dirección de memoria (dirección efectiva) que contiene el dato estará almacenada en esta posición de memoria y hablaremos de direccionamiento indirecto a memoria.
La desventaja principal de este modo de direccionamiento es que necesita un acceso más a memoria que el directo. Es decir, un acceso a memoria para el direccionamiento indirecto a registro y dos accesos a memoria para el direccionamiento indirecto a memoria; por este motivo este segundo modo de direccionamiento no se implementa en la mayoría de las máquinas.

Proceso de ensamblado y ligado

EDICION 
Los archivos fuente de código ensamblador deben estar en formato ASCII standard. Para esto puede usarse cualquier editor que permita crear archivos sin formato, e.g. Edlin, Edit, Write, El editor del Turbo Pascal, Works, Word, WordStar, etcétera. Las declaraciones pueden ser introducidas en mayúsculas y/o minúsculas. Una buena práctica de programación es poner todas las palabras reservadas (directivas e instrucciones) en mayúsculas y todo lo del usuario en minúsculas para fines de facilidad de lectura del código. Las sentencias pueden comenzar en cualquier columna, no pueden tener más de 128 caracteres, no se permiten líneas múltiples ni códigos de control, y cada línea debe ser terminada con una combinación de line-feed y carriage-return. Los comentarios se declaran con; y terminan al final de la línea. 
ENSAMBLADO 
El ensamblado se lleva a cabo invocando al MASM. Este puede ser invocado, usando una línea de comando, de la siguiente manera: MASM archivo [,[objeto][,[listado][,[cross]]]]][opciones][;] Dónde:
Objeto. - Es el nombre para el archivo objeto.
Listado. - Nombre del archivo de listado de ensamblado. cross. Es un archivo de referencias cruzadas. LINK De la misma forma que el ensamblado, la fase de liga se lleva a cabo con el LINK. Este puede ser invocado de la misma forma que el MASM. Los parámetros que este requiere son: LINK objeto [,[ejecutable][,[mapa][,[librería]]]]][opciones][;] dónde: 
Objeto. - Es el nombre para el archivo .OBJ
Ejecutable. - Nombre del archivo .EXE
Mapa. - Nombre del archivo mapa
Librería. - Nombre del archivo biblioteca de rutinas 
EJECUCION 
Para la ejecución del programa simplemente basta teclear su nombre en el prompt de MS-DOS y teclear ENTER. Con esto el programa será cargado en memoria y el sistema procederá a ejecutarlo. El proceso completo para poder crear un programa ejecutable con el Microsoft Macro Assembler se muestra abajo. 

Características del Proceso de Ensamblado y ligado.

  1. El programa utiliza un editor de texto para crear un archivo de texto ASCII, conocido como archivo de código fuente.
  2. El ensamblador lee el archivo de código fuete y produce un archivo de código objeto, una traducción del programa a lenguaje máquina. De manera opcional, produce un archivo de listado. Si ocurre un error, el programador debe regresar al paso 1 y corregir el programa. 
  3. El enlazador lee el archivo de código objeto y verifica si el programa contiene alguna llamada a los procedimientos en una biblioteca de enlace. El enlazador copia cualquier procedimiento requerido de la biblioteca de enlace, lo combina con el archivo de código objeto y produce el archivo ejecutable. De manera opcional, el enlazador puede producir un archivo de mapa.
  4. La herramienta cargadora (loader) del sistema operativo lee el archivo ejecutable y lo carga en memoria, y bifurca la CPU hacia la dirección inicial del programa, para que éste empiece a ejecutarse.
Desplegado de mensajes en el monitor.
Para poder desplegar un mensaje en el monitor es necesario que el texto a desplegar se escriba en la RAM de visualización de video, para después ser enviado al monitor mediante el controlador de video. El controlador de video es en sí un microprocesador de propósito especial, que libera a la CPU principal del trabajo de controlar el hardware de video.

Para hacer esto se pueden utilizar varios de los servicios con los que cuenta el lenguaje ensamblador, los cuales se describen con detalle en el apéndice A.
Para detener la pantalla y permitir al usuario ver lo que se ha desplegado en la misma se utiliza el servicio 00 de la interrupción 16h.
Ejemplo:
mov dx,65       ->           Asignar el Valor 65 ASCII al registro DX
mov ah,02h     ->           Asignar el valor 02h al registro AH, que corresponde al servicio de                                                             impresión de un caracter.
int 21h          ->           Llamada a la interrupción 21h, de la que se ejecutará el servicio 02h.


Comentarios