Ensamblador
El lenguaje ensamblador es un lenguaje de bajo nivel cuyas instrucciones se suelen corresponder una a una con las instrucciones del ordenador, y con la posibilidad de poder definir, por ejemplo, macroinstrucciones
Este lenguaje es totalmente dependiente del modelo de procesador
Para poder estudiar este lenguaje con un microprocesador real se ha elegido el 8086, ya que es uno de los más utilizados en la actualidad en ordenadores de tipo PC
La principal característica de ese microprocesador es que es capaz de trabajar con operandos de 16 bits
Los ordenadores de tipo PC usan las operaciones básicas en 16 bits del 8086 y si el procesador es de 32 bits se le añaden un repertorio nuevo de operaciones en 32 bits. Si es de 64 bits entonces el repertorio de operaciones incluidas son de 16 bits, de 32 bits y un nuevo repertorio de 64 bits
Arquitectura básica del 8086
La arquitectura interna del 8086 se compone de dos partes diferenciadas: la Unidad de Ejecución y la Unidad de Interfaz con el bus
La tarea principal de la Unidad de Ejecución es ejecutar las instrucciones que extrae de la cola de espera, a donde llegan procedentes de la MP (Memoria Principal)
El trabajo principal de la Unidad de Interfaz con el bus es buscar y traer las instrucciones de la MP. Para ello tendrá que generar la dirección de la instrucción a ejecutar
Registros generales o de datos
Hay 4 registros de 16 bits y cada uno tiene una utilidad concreta:
- AX
Registro acumulador, se utiliza con las operaciones aritméticas - BX
Registro de base, se utiliza para acceder a vectores, tablas, etc
Mediante el uso de una dirección base que indica cual es el primer elemento y una dirección de desplazamiento que es el valor que se le suma a la dirección base para poder alcanzar el elemento deseado - CX
Registro contador, se utiliza para contar en bucles e instrucciones de tipo repetitivo - DX
Registro de datos, tiene dos usos particulares- Complementar al registro AX en las operaciones aritméticas multiplicación y división
- Contiene direcciones de puerto para instrucciones de entrada / salida
Estos 4 registros tiene la siguiente propiedad común, aunque son de 16 bits, se pueden considerar cada uno de ellos como 2 registros independientes de 8 bits. De este modo podemos designar los bits más altos o significativos como Hight (al registro se le renombra con H al final: AH, BH, CH, DH) y los más bajos o menos significativos como Lower (al registro se le renombra con L al final: AL, BL, CL, DL)
Registros de segmento: Segmentación
Hay 4 registros de 16 bits y cada uno tiene una utilidad concreta:
- CS
Segmento de código, es el que define la zona de memoria donde se encuentran las instrucciones a ejecutar o de programa - DS
Segmento de datos, es el que define la zona donde se encuentran los datos que van a ser usados en el programa - SS
Segmento de stack o pila, define la zona de memoria que se va a utilizar como una pila - ES
Segmento extra, como su nombre indica contiene la dirección del segmento extra, que se utiliza cuando se sobrepasa la capacidad de 64 kbytes del segmento de datos y para realizar determinadas transferencias de datos entre segmentos
Bus de datos: lineas por las que se transmiten los datos
Anchura del bus de datos: número de lineas eléctricas del bus por las que se transmiten los datos, en el 8086 son de 16 bits
Bus de direcciones: lineas por las que se transmiten las direcciones
Anchura del bus de direcciones: número de lineas eléctricas del bus por las que se transmiten las direcciones, en el 8086 son de 16 bits
Por tanto, las direcciones deberían ser de 16 bits, sin embargo, en el 8086 son de 20 bits. Esto es debido a que el número de direcciones distintas sería 2^{16}=64K, pero como son muy pocas, nos interesa que sean de 20 bits, ya que 2^{10}=1M
Para calcular la dirección física necesitamos un segmento y un desplazamiento, usando siempre valores en hexadecimal, con lo que tendremos un primer registro de 16 bits al que se añadirá un 0 a su derecha y un segundo registro de 16 bits
Como notación se usa Segmento:Desplazamiento
El cálculo de la dirección física se realizará:
Segmento x 10(h) + Desplazamiento
Ejemplos de Segmento:Desplazamiento
- 0000:1050\Rightarrow 0000\cdot 10+1050=0150
- 0010:0F50\Rightarrow 0010\cdot 10+0F50=0150
- 0100:0050\Rightarrow 0100\cdot 10+0050=0150
- 0105:0000\Rightarrow 0105\cdot 10+0000=0150
Como puede apreciarse en los ejemplos, distintas combinaciones de segmentos y desplazamientos pueden darnos la misma dirección física. Esta situación no es un error, es debido a que las direcciones de los segmentos se solapan entre sí
Podemos tener tantos números de segmentos distintos como combinaciones distintas puedan hacerse con la dirección base de segmento. Como tiene 16 bits entonces tenemos 2^{16} combinaciones por lo que tenemos 64\cdot K direcciones distintas
Podemos tener tantos números de direcciones distintas en cada segmento como combinaciones distintas puedan hacerse con el desplazamiento. Como tiene 16 bits entonces tenemos 2^{16} combinaciones por lo que tenemos 64\cdot K direcciones distintas
Se podría pensar que como tenemos 64\cdot K segmentos y 64\cdot K direcciones, tendríamos 64\cdot 64=2G direcciones físicas. Sin embargo, como las direcciones están solapadas este número de direcciones es incorrecto
Las direcciones válidas de comienzo de segmento tienen la propiedad de acabar en 0. Por tanto, ya que en hexadecimal son 10, al pasar de hexadecimal a decimal obtenemos que el número de direcciones es 16