Tal y como indica el titulo ahora os voy a hablar sobre el lenguaje ensamblador. 

¿Que es el lenguaje ensamblador? 
Pues el lenguaje ensamblador es un lenguaje de nivel medio, es decir, es algo intermedio entre el lenguaje humano y el lenguaje del procesador. Normalmente esta compuesto por instrucciones cortas de 3 o 4 caracteres seguidas de unos parĆ”metros denominados parĆ”metro fuente y parĆ”metro destino. 

Normalmente la sintaxis de las instrucciones dependen del tipo de procesador y ademas los programas escritos en ensamblador solo se pueden ejecutar correctamente en el procesador para el que han sido programados. O sea un programa en ensamblador escrito para procesador Intel solo funcionara correctamente para los procesadores Intel y va a provocar efectos diferentes en un procesador Athlon de AMD. 

A continuación veremos mĆ”s a fondo que es el lenguaje ensamblador de la arquitectura Intel 8086. 

Introducción en la arquitectura Intel 8086 
Antes de poner nos a programar en ensamblador tenemos que conocer cual es la arquitectura de los procesadores Intel, o sea, conocer como estĆ”n organizados los componentes internos del procesador. Esto es necesario por que el lenguaje ensamblador se encarga de gestionar los componentes internos del procesador mediante instrucciones cortas. Como por ejemplo para sumar dos nĆŗmeros primero tenemos que ordenar en dirección de memoria dichos nĆŗmeros y a continuación realizar la suma mediante la instrucción: add destino, fuente. En dichas instrucción vamos a indicar cuales son las direcciones de memoria en las que estĆ”n almacenados los dos datos. Una vez que la suma ha sido realizada el resultado se almacena en el dirección de memoria indicada por destino. 

¿Como estĆ” organizada la memoria en Intel 8086?: pues para la organización del I-8086 se ha utilizado el modelo Litle Endian que quiere decir que las primeras instrucción estĆ”n en las dirección de memoria mas baja y las ultimas instrucciones estĆ”n almacenadas en las ultimas direcciones de memoria (cada dirección de memoria tiene asignado un nĆŗmero presentado normalmente en codificación hexadecimal). 

¿Que partes tiene el procesador?: pues el procesador o CPU del I-8086 tienes las siguientes partes: 
- Registro: son memorias internas de la CPU. Son las mĆ”s rapidas del ordenador. Normalmente la información que vamos a procesar se almacena en estos registro para aumentar las velocidades de procesamiento. MĆ”s adelante veremos cuales son estos registros y como se utlizan 
- Unidad de Control: se encarga de distribuir las tareas que tienen que realizar todas las partes del ordenador y cuando las tiene que realiza. 
- Unidad AritmĆ©tico-Lógica: se encarga de realizar cĆ”lculos, realizar comparaciones etc. 

Ademas del procesador el ordenador tiene dispositivos de entrada/salida como la pantalla, teclado, ratón, impresoras etc. AsĆ­ que los buses que se encargan de distribuir la información por todas partes. El esquema es el que estĆ” a continuación: 

 

Registros del procesador 
El I-8086 tiene 14 registro de 16 bits cada uno. A continuación se describe cada uno de ello: 

- 4 registros de propósito general: esto 4 registro son AX, BX, CX, DX. Cada uno de ellos esto formado por otros 2 registros de 8 bits cada uno. El registro AX estĆ” formado por AH (byt de mas peso) y AL (byt de menos peso). El registro BX estĆ” formado por BH (byt de mas peso) y BL (byt de menos peso). El registro CX estĆ” formado por CH(byt de mas peso) y CL (Byt de menos peso). El registro DX estĆ” formado por DH (byt de mas peso) y DL (byt de menos peso). Cada uno de ellos se puede utilizar para lo que queramos aunque para algunas instrucciones utilices preferentemente algunos de ellos. 

4 registros de direcciones: Almacenan direcciones efectivas 
utilizadas por distintas instrucciones. SI (source index), DI (destination index), BP 
(base pointer), SP (stack pointer). 

4 registros de segmento: Almacenan identificadores de segmento, que 
combinados con los registros de dirección (o los de propósito general) identifican 
direcciones fĆ­sicas. CS (code segment), DS (Data segment), SS (Stack 
segment), ES (Extra data segment). 

2 registros de propósito especĆ­fico: 
IP – Dirección de la instrucción a ejecutar (combinado con CS) 
PSW – Palabra de estado del procesador, o registro de flags. 

¿Que es la palabra de estado del procesador? 
La palabra de estado o registro de flags es un registro de la CPU de 16 bits y cada uno de estos bits tiene una significado especifico. A continuacion veremos cuales son: 

- CF: acarreo / desbordamiento natural +, -, >>, << 
- PF: Paridad = 1 si nĆŗmero par de bits 1 en el byte de menos peso del resultado 
- AF: Acarreo auxiliar (del bit 3 al 4) 
- ZF: = 1 si el resultado = 0 
- SF: = 1 si el resultado < 0 
- TF: Bit de traza. Manipulado por programa 
- IF: MĆ”scara de interrupción. Si 0, la UC no acepta interrupciones externas 
- DF: sentido de incremento de punteros en instrucciones de cadena. Si 0, los punteros se incrementan. Si 1, se decrementan bit 11 OF Desbordamiento entero: el resultado no puede representarse en complemento a 2. 

Una vez que hemos visto que son los registro del procesador Intel 8086 el esquema conceptual se queda asĆ­: 

 

Instrucciones del lenguaje Ensamblador del I-8086 
- Suma: para suma dos nĆŗmeros se utiliza la instrucción add 
Formato: add destino, fuente 
Descripción: Suma destino con fuente y almacena el resultado en destino. Destino y fuente puedes ser direcciones de memoria, registros o datos directos. 

- Restar: para restar dos nĆŗmeros se utliza la instrucción sub 
Formato: sub destino, fuente 
Descripción: resta destino y fuente y almacena el resultado en destino. Igual que la suma destino y fuente pueden ser direcciones de memoria, registros o datos directos. 

- Mover: mover un dato desde fuente a destino se utliza la instrucción mov 
Formato: mov destino, fuente 
Descripción: mueve el valor del operando fuente en la dirección que apunta el operando destino 

Para mĆ”s información podeis consultar el manual del ensamblador. No os voy a contar todas las instrucciones por que la lista es muy larga. TambiĆ©n podĆ©is realizar bĆŗsquedas en google poniendo manual de ensamblador seguido del procesador con el cual vais a programar. 

Los vĆ­deos que estĆ” a continuación es solamente educativo. NO enseƱa a hachear!!! Solamente da a conocer que habilidades hay que tener. 



 una pequeƱa base de los que es el lenguaje ensamblador. Ahora veremos que son las interrupciones en el Intel 8086 y para que se utilizan.

¿Que son las interrupciones del Intel 8086?
Pues las interrupciones son seƱales enviadas por alguno de los perifericos que advierten al procesador que ha habido actividad en dicho perifĆ©rico. Por ejemplo cuando pulsamos alguna tecla, el teclado envĆ­a una seƱal de que ha sido pulsada una tecla y envĆ­a el código binario de la tecla pulsada. A continuación veremos mĆ”s a fondo cual es el proceso de las interrupciones y que tipos hay. 

¿Como se gestionan las interrupciones del Intel 8086?
Las interrupciones del Intel 8086 se gestionan por el Controlador de interrupciones. Dicho controlador tiene cuatro registro (memorias) de 16 bits cada uno. Cada uno de estos registros tiene una función especifica y gracias a ellos se van a gestionar funciones como las prioridades de los perifericos, peticiones de servicio etc. Estos registro son:
- Registro IRR: marca las peticiones de los perifericos
- Registro IMR: esta en el puerto 21h y da permisos a las peticiones de las interrupciones. Pasa si es 0 y no pasa si es 1. 
- Registro IPR: lógica que selecciona la prioridad
- Registro ISR: marca que peticiones se estan activando
- Registro de Control: estĆ” en el puerto 20h y es el encargado de avisar al procesador que ha acurrido una interrupción. 

El controlador de interrupciones tiene 8 entrada para los distintos perifericos y la habilitación es por flanco (es decir, es controlado por la seƱal del reloj) y es programable. Es decir cambiando los valores del registro de control y del registro IMR podemos controlar las interrupciones. 

Ya he mencionado que el controlador de interrupciones tienen 8 entradas. Estas 8 entradas podeis verlas en la imagen de abajo (hay que tener en cuenta que el mĆ”s prioritario es el reloj y el menos prioritario es la impresora):



En la imagen podemos observar que se nos muestra la dirección de memoria (en dĆ©cima) en la que estĆ” ubicado cada uno de los perifĆ©ricos. En dicha dirección de memoria se almacena el Driver del Sistema Operativo que se encarga de controlar dicho perifĆ©rico. Ahora teniendo en cuenta que el controlador de interrupciones es programable podemos programar nuestros propios Drivers y sustituir los en las direcciones de memoria indicadas por el vector de interrupciones. Esta sustitución de Driver se hace en el caso de que tenemos que programar una aplicación que tenga funciones especificas de los perifĆ©ricos. Por ejemplo en los juegos las distintas teclas tienen funciones especificas por tanto al iniciar el juego tenemos que poner nuestro propio Driver y al acabar el juego tenemos que restablecer el Driver del Sistema Operativa para que el teclado funcione con normalidad. 

Por ultimo os tengo que comentar que las interrupciones forman parte del proceso de Entrada/Salida (E/S) del ordenador. Este proceso estĆ” descrito a continuación:



En la imagen podemos observar que la E/S de datos se realiza mediante una sincronización (que puede ser por encuesta o por interrupción) y a continuación se hace una trasferencia (que puede ser programada o por DMA). 

La diferencia entre la sincronización por encuesta y la sincronización por interrupciones es que en la encuesta el ordenador nos piden obligatoria mente la activación de alguno de los perifĆ©ricos (por ejemplo pulsar una tecla) mientras que en la interrupción la CPU hace su trabajo y si se activa alguno de los perifĆ©ricos realiza una transferencia, es decir, tratar la interrupción mediante programación (si la transferencia es programada). A continuación os dejo un ejemplo muy sencillo de sincronización por interrupción con transferencia programada:


TITLE nombre_del_programa
MODEL small
.STACK 100h ; asignamos a la pila tamaƱo 100h
.DATA ; empiza el segmento de declaracion de variables
;--------------------------------------------------------------------
;BLOQUE DE VARIABLES
;--------------------------------------------------------------------
tecla db ? ; almacena el valor de una tecla que se ha pulsado
crono db 0 ; variable de cronometro. almacena la cantidad de veces que el reloj de la CPU envia una seƱal
;---------------------------------------------------------------
; DATOS: VECTOR DE INTERRUPCIONES
;---------------------------------------------------------------
ip_reloj DW 0 ; ip rut. serv. reloj del sistema
cs_reloj DW 0 ; cs rut. serv. reloj del sistema
ip_tecla DW 0 ; ip rut. serv. teclado del sistema
cs_tecla DW 0 ; cs rut. serv. teclado del sistema
IRQ0 EQU 8*4 ; d.e. de la interrupción de reloj
IRQ1 EQU 9*4 ; d.e. de la interrupción de teclado
.CODE ; A PARTIR DE AQUI EMPIEZA EL PROGRAMA
;Esto hay que hacer lo siempre cuando empiza un programa
principio: mov ax,@DATA ; almacenamos en reg. ax la dir. de memoria en la que empieza nuestro programa
mov ds,ax ; movemos el valor de reg. ax en reg. ds.
;--------------------------------------------------------------------
;CAMBIA LOS DRIVERS DEL SISTEMA OPERATIVO POR LOS NUESTROS
;--------------------------------------------------------------------
;CAMBIO DE RUTINA DE SERVICIO DEL S.O.
xor ax,ax ; ponemos ax=0
mov es,ax ; moves el valor de ax en es

;Rutina del reloj. Desactivamos el Driver del Sistema Operativo
;y almacenamos en las variables ip_reloj y cs_reloj las dirección
;de memoria en la que esta almacendo el Driver del reloj
mov si,IRQ0
mov ax,es:[si]
mov ip_reloj,ax
mov ax,es:[si+2]
mov cs_reloj,ax

;Activamos nuestro propio Driver de teclado
cli
mov ax,OFFSET reloj ;reloj_int: empieza rutina de servicio del reloj
mov es:[si],ax
mov ax,cs
mov es:[si+2],ax
sti


;Rutina del teclado.Desactivamos el Driver del Sistema Operativo
;y almacenamos en las variables ip_tecla y cs_tecla las dirección
;de memoria en la que esta almacendo el Driver del teclado
mov si,IRQ1
mov ax,es:[si]
mov ip_tecla,ax
mov ax,es:[si+2]
mov cs_tecla,ax

;Activamos nuestro propio Driver de teclado
cli
mov ax,OFFSET teclado
mov es:[si],ax
mov ax,cs
mov es:[si+2],ax
sti

;---------------------------------------------------------------
;CƓDIGO DEL PROGRAMA PRINCIPAL
;---------------------------------------------------------------
; AQUI TIENE QUE PONER EL CƓDIGO DEL PROGRAMA PRINCIPAL
; AQUI TIENE QUE PONER EL CƓDIGO DEL PROGRAMA PRINCIPAL
; AQUI TIENE QUE PONER EL CƓDIGO DEL PROGRAMA PRINCIPAL
; AQUI TIENE QUE PONER EL CƓDIGO DEL PROGRAMA PRINCIPAL
;---------------------------------------------------------------
;RECUPERAMOS LOS DRIVERS DEL S.O.
;---------------------------------------------------------------
xor ax,ax ; ponemos ax=0
mov es,ax ; movemos el valor de ax en es
;Recuperacion rutina de servicio reloj del S.O.
cli ; desactivamos las interrupciones para que no interrumpan el programa
mov si,IRQ0
mov ax,ip_reloj
mov es:[si],ax
mov ax,cs_reloj
mov es:[si+2],ax
sti
 ; activamos las interrupciones

;Recuperacion rutina de servicio teclado del S.O.
xor ax,ax
mov es,ax


cli ; deactivamos las interrupciones durante el proceso de camibio de driver del teclado
mov si,IRQ1
mov ax,ip_tecla
mov es:[si],ax
mov ax,cs_tecla
mov es:[si+2],ax
sti
 ; activamos las interrupciones

mov ah,4Ch ;SIEMPRE: devolver el control
int 21h ;al sistema operativo
;---------------------------------------------------------------
;RUTINAS DE SERVICIO
;Rutina de servicio del reloj
;---------------------------------------------------------------
reloj:
push ax

inc crono
 ; incrementamos la variable crono con una unidad

;EOI: proceso en el cual indicamos al registro de control de interrupciones que se ha acabado la interrupción
mov al,20h ; almacenamos en el registro al el dato 21h
out 20h,al ; escribimos el datos 21h (del reg. al) en el puerto 21h (registro de control del controlador de interrupciones)

pop ax
iret
 ; volvemos en la dir. de memoria en la que ha sido interrumpido el programa principal
;-----------------------------------------------------------------
;RUTINA DE SERVICIO DEL TECLADO
; Es nuetro propio DRIVER DE TECLADO
;----------------------------------------------------------------
teclado:
sti

push ax ; almacenamos en la pila el valor de ax para no interrumpir el correcto fucionamiento del programa principal
pushf ; almacenamos en la pila la palabra de estado o los flags de la CPU

in al,60h ; leemos del puerto 60h la tecla que se pulsado
PUSH AX ; almacenamos en el registro ax la tecla pulsada y lo guardamos en la pila

; es un proceso en el cual vamos a indicar al procesador que se ha liedo una tecla y que podemos leer una nueva
IN AL, 61H ;al = Registro de control (61h)
OR AL, 10000000B ;al = 1XXXXXXX
OUT 61H, AL ;Bit de strobe = 1 .Es decir se autoriza la lectura de otro dato del teclado
AND AL, 011111111B
OUT 61H, AL

;FIN 

;Gestion de tecla de pausa en partida
POP AX ;Recuperamos la tecla que se ha pulsado
mov tecla,a ; almacenamos en la variable tecla el código de la tecla que se ha pulsado

;EOI: proceso en el cual indicamos al registro de control de interrupciones que se ha acabado la interrupción
mov al,20h ; almacenamos en el registro al el dato 21h
out 20h,al ; escribimos el datos 21h (del reg. al) en el puerto 21h (registro de control del controlador de interrupciones)

popf ; recuperamos la palabra de estado de la CPU
pop ax ; recuperamos el valor antiguo del registro ax
iret ; volvemos en la dirección de memoria en la que ha sido interrupmido el programa principal

END principio



En proceso es el siguiente: al empezar el programa el Sistema Operativo asigna una dirección de memoria en la que empieza nuestro programa. AsĆ­ que se recupera nuestro programa del disco duro y se almacena en la RAM a partir de la dirección asignada en la linea 1 de nuestro programa. A continuación nosotros hemos decidido cambiar los Drivers de teclado y de reloj del Sistema Operativo por nuestros Propios Drivers que hemos llamado reloj y teclado. A continuación debe ir el código del programa principal de la aplicación que vamos a programar y antes de finalizar el programa debemos recuperar los Drivers del teclado y reloj del Sistema Operativo para que pueda funcionar con normalidad el ordenador. Para finalizar devolvemos el control al Sistema Operativo y el programa acaba. 


Las instrucciones del lenguaje ensamblador las podĆ©is consultar en la dirección web de Intel: Manual de ensamblador Intel
http://www.intel.com/products/processor/manuals/index.htm
Generalmente los ordenadores estĆ”n formadas por los siguientes dos componentes:Hardware y Software. El Hardware es la parte fĆ­sica del ordenador, es decir, todo lo que podemos ver y tocar (toda la parte electrónica). El Software es la parte lógica del ordenador, es decir, todos los programas que tenemos instalados (Sistema operativo, juegos, drivers etc.). Dichos dos componentes estĆ”n formadas por su parte por otroscomponentes que vamos a ver a continuación. 

SOFTWARE

El Software se suele llamar parte lógica por que los programas que tenemos instalados no los podemos ver y tocar. Dichos programas estĆ”n formadas por un conjunto de instrucciones (tambiĆ©n llamados comandos) que indican al ordenador que tiene que hacer.

Estas instrucciones juntas forman un lenguaje de programación. Teniendo en cuenta que existen muchos lenguajes de programación ¿como que un ordenador entiende a todos estos lenguajes? Pues en realidad los lenguajes de programación que utilizamos hoy en dia son conocidos como lenguajes de alto nivel. Dichos lenguajes se entienden solo por las personas y no se entiende por ordenadores. Su propósito es de facilitar las tareas de la programación ya que el lenguaje del ordenador (tambiĆ©n llamado lenguaje maquina) es mucho mas complicado para entender por los humanos y ademĆ”s para programar en lenguaje de maquina es necesario conocer muy bien toda la parte electrónica. AsĆ­ que los lenguajes de alto nivel quitan la necesidad de conocer la parte electrónica y el aprendizaje sobre la programación es mucho mĆ”s fĆ”cil.

Una vez que ha sido programada una aplicación en algĆŗn lenguaje de alto nivel, este tiene que ser traducido a lenguaje de maquina para que el ordenador pueda entender lo. Esta traducción se realiza mediante programas llamados compiladores (o interpretes segĆŗn el lenguaje que utilizamos). Los compiladores tambiĆ©n juegan el papel de editores para dichos lenguajes de alto nivel, es decir, utilizamos el compilador para escribir el programa en lenguaje de alto nivel y a continuación lo utilizamos para traducir la aplicación a lenguaje de maquina para que pueda entender lo el ordenador.

¿Compiladores o intĆ©rpretes?
La diferencia entre ambos es que los intĆ©rpretes traducen y ejecutan las instrucciones lĆ­nea por lĆ­nea, mientras que los compiladores traducen todas las instrucciones y a continuación se ejecutan todas las instrucciones. AsĆ­ que ¿cual de los dos utilizar? Pues esto depende del lenguaje de programación que vamos a utilizar por que cada lenguaje de alto nivel tiene su propia estructura, instrucciones y requisitos.

HARDWARE

El Hardware tiene tres parte fundamentales: Procesador, memoria y perifericos. A continuación vamos a ver cada uno de ellos.

El Procesador
Tambien se denomina CPU (Unidad central de Procesamiento) y proviene del inglesCentral Processing Unit. Es una de las partes mĆ”s importantes por que se encarga de manipular a toda la información, realizar cĆ”lculos, ejecutar instrucciones etc. Es considerado cerebro y corazón del ordenador. EstĆ” construido por un circuito integrado que contiene millones de transistores conocidos tambiĆ©n como puertas lógicas.

Componentes del procesador
Sus componentes fundamentales son:
1. Unidad de control (UC): se encarga de buscar instrucciones dentro de la memoria, decodificar las y ejecutar las utilizando la ALU. 
2. Unidad aritmĆ©tico-lógica (ALU): se encarga de ejecutar las instrucciones que les envĆ­a la UC. Cada una de las instrucciones tiene un formato determinado que veremos en otros artĆ­culos. 
3. Registros: son memorias internas del procesador y son las mÔs rÔpidas del ordenador. Son utilizados por los programas que estÔn actualmente en ejecución para mejor la velocidad del procesamiento
3. Buses: es la vĆ­a de comunicación por la cual viaja toda la información. Cada uno de los componentes del ordenador estĆ” conectado a los buses y tiene acceso a estos en cada momento. 

La Memoria 
La memoria es la parte que se encarga de almacenar la información siendo esta datos de los usuarios, las instrucciones de los programas etc. Hay dos tipos de memorias:
1. RAM: proviene del ingles Random Acces Memory (Memoria de Acceso Aleatorio). Es una memoria en la que podemos escribir y leer datos a gran velocidad por que podemos acceder aleatoriamente en sus posiciones sin la necesidad de pasar por las posiciones anteriores. Es memoria volĆ”til, es decir, cuando se corta el suministro de electricidad la información se pierde. En esta memoria se almacenan las instrucciones de todos los programas que tenemos iniciados y tambiĆ©n el resultado de los cĆ”lculos que realiza el procesador. A mĆ”s memoria RAM mĆ”s programas podemos iniciar.
2. ROM: proviene del ingles Read Only Memory (Memoria sólo de Lectura). Es una memoria no volĆ”til y de acceso aleatorio. Se utiliza para almacenar la información relevante acerca de la configuración de los dispositivos internos del ordenador. 

Los perifĆ©ricos 
Los perifĆ©ricos son componentes fuera de la carcasa del ordenador. Esto son dispositivos como la pantalla, la impresora, escĆ”ner, ratón, teclado etc.

¿COMO FUNCIONA EL ORDENADOR?
Una vez que hemos encendido el ordenador se ejecutan la secuencia de operaciones de la Memoria ROM (BIOS) y chequea los componentes instalados. Luego ejecuta instrucciones del Sistema Operativo trasladĆ”ndolas en la memoria RAM. 

Una vez que se han trasladado las instrucciones del S.O. en la RAM veremos la primera pantalla. Entonces podemos activar cualquier programa (sus instrucciones se llevan en la RAM) y podemos introducir datos con los periféricos de entrada (teclado, ratón etc.) Mientras esto la CPU procesa y ejecuta las instrucciones y datos que estÔn temporalmente almacenadas en la RAM.

Una vez que se ha acabado el procesamiento de la información podemos direccionar los resultados hacia un perifĆ©rico de salida (p.e. el monitor).Cuando estamos finalizando, todos los programas de la RAM se desactivan y el ordenador se apaga.