ASM
POR AESOFT
Corregido
y pasado a HTML por dek_Oin
LECCIÓN
2:
DIRECCIONAMIENTO
DE MEMORIA EN EL
8086
SEGMENTACIÓN
Hola a todos los seguidores del curso de ensamblador de
AESOFT.
En esta lección vamos a ver cómo direcciona la memoria
el 8086,
es decir, cómo el 8086 accede a cada una de las
posiciones de
memoria.
La forma en que la CPU construye las direcciones de
memoria es muy
importante para la programación del sistema, debido a
que constantemente
utilizamos instrucciones de transferencias de datos, de
acceso a funciones de la BIOS, del DOS, etc.
Más adelante estudiaremos la BIOS. Valga por ahora que
es un conjunto de
utilidades y procedimientos grabados en la ROM (memoria
de solo lectura),
los cuales se encargan de acceder al nivel más bajo en
cuanto a
programación se refiere. Es decir, estas rutinas se
encargan de manipular
el hardware por nosotros.
BIOS son las siglas de Basic Input Output System (Sistema
básico de
entrada/salida).
En cuanto al DOS (sistema operativo de disco), decir que aquí
nos referíamos no a las utilidades o comandos que trae consigo, que es lo típico
que
se enseña en academias e institutos, sino a la estructura interna del mismo:
interrupción 21h, 24h, etc.
Ya veremos también qué es una interrupción.
Bien, antes de entrar de lleno en el tema, conviene saber
un poco del
por qué del mismo. Es decir, qué llevó a que fuera de
esta forma y no
de otra.
A principio de los años 80, Intel (fabricante de la
familia de procesadores
80x86) se propuso dar un gran paso adelante con respecto
a la competencia.
En aquel tiempo los microprocesadores que imperaban entre
los ordenadores
domésticos eran de 8 bits, es decir, tenían un ancho de
bus de datos de
8 bits, el tamaño de palabra de memoria era de 8 bits, y
los registros
del procesador eran de 8 bits. Un claro ejemplo de esto
fue el
microprocesador Z80 (de la empresa Zilog), el cual estaba
incorporado
en máquinas tan famosas como los spectrum, amstrad, msx,
etc.
Como he dicho, el ancho del bus de datos era de 8 bits. Esto quiere decir
que todas las transferencias de datos que se hicieran se harían
de 8 en
8 bits, es decir, byte a byte.
Pues bien, aunque el microprocesador era de 8 bits, y la mayoría
de
registros también lo eran, había alguno mayor (16
bits).
Me estoy refiriendo sobre todo al registro de direcciones
que era de
16 bits. De esta forma, un amstrad cpcA464 podía acceder
a 64 kb de memoria.
64 Kb es la máximo que podía direccionar el z80
original.
En ese momento Intel se planteó superar esa barrera de
las 64 Ks, pero
teñía un problema. El z80 por ejemplo, había conseguido
tener registros
de 16 bits cuando el microprocesador es de 8. Pero pasar
de 16 bits
de capacidad en registros en aquellos momentos no era
posible para los
microprocesadores. Es decir, no había suficientes
avances tecnológicos
como para conseguir tamaños de registros mayores en un
microprocesador.
De tal manera que había que buscar una fórmula
diferente... Y ah¡ es
cuando surgió el tema de los segmentos que tantos
quebraderos de cabeza
a dado hasta ahora y sigue dando.
A Intel se le ocurrió la idea de construir una dirección
de 20 bits de
ancho y colocarla en el bus de direcciones para poder
dirigirse a la
memoria. Pero al ser los registros de 16 bits, sólo había
una solución
posible para crear este ancho de 20 bits: Usar 2
registros de 16 bits!!!
. El 8086 divide el espacio de direcciones (1 Mbyte) en
segmentos, cada uno
de los cuales contiene 64 Kb de memoria (la máxima
direccionable por un
solo registro).
Entonces, para direccionar una posición de memoria nos
valemos de dos
registros: Registro de segmento y de offset.
Ya vimos en la lección anterior que había varios
registros de segmento:
cs (registro de segmento de código), ds (de datos), etc.
Pues bien, este primer registro (de segmento), indica donde
comienza el
trozo de 64 Kb que buscamos.
Y el segundo registro (el de offset), contiene el
desplazamiento dentro
de ese segmento.
Bien. Hemos visto que son necesarios 2 registros para
direccionar ese
Mbyte de memoria, y tenemos un bus de direcciones de 20
bits.
Esto nos conduce a que el microprocesador debe realizar
unas operaciones
sobre estos dos registros para obtener la dirección física
de 20 bits.
Esto se logra de la siguiente manera:
El 8086 mueve el valor del segmento 4 bits a la izquierda
y le suma el
valor del desplazamiento para crear una dirección de 20
bits.
Gráficamente:
Tenemos dos registros de 16 bits.
DS:
XXXXXXXXXXXXXXXX BX:
XXXXXXXXXXXXXXXX
15 87
0
15 87
0
Byte alto Byte bajo
Byte alto Byte bajo
(más significativo)(menos significativo)
El primer registro, es el de segmento (en este caso,
segmento DS, de
datos). El segundo registro es el de offset o desplazamiento.
En este caso utilizamos el registro BX para direccionar dentro de
el segmento. Podíamos haber utilizado también el
registro SI, el DI,
etc.
A partir de estos dos registros, debemos acceder a una
posición de
memoria física dentro del Mbyte de que disponemos para el 8086.
Pongamos que el registro DS tiene el valor 0B800h (en hexadecimal)
(podéis utilizar SBACALCU de SAN BIT para hacer los
cambios de base,
y trabajar con bases diferentes a la decimal). También
para la decimal, por supuesto).
Y el registro BX contiene el valor 0037h.
Tenemos pues (en binario):
DS: 1011100000000000
BX: 0000000000110111
Para obtener la dirección física de memoria, y teniendo
en cuenta todo lo
dicho relativo a segmentos, el microprocesador acturaría
as¡:
(Gráficamente)
Haría una suma de la siguiente forma:
DS:
1011100000000000
BX: +
0000000000110111
_____________________
10111000000000110111
Obteniendo as¡ la dirección de 20 bits necesaria para
cubrir todo
el Mbyte.
Si ese número (10111000000000110111) que está en
binario, lo pasamos
a hexadecimal, tenemos que la dirección física
correspondiente a la
anterior segmentada es: 0B8037h.
De todo lo anterior, se desprende que los segmentos
empiezan siempre en
direcciones divisibles por 16. Más técnicamente: cada
segmento comienza
en una dirección de
párrafo. Un párrafo son 16 bytes.
Por supuesto nunca habrá un segmento que empiece en una
dirección impar,
por ejemplo.
Como ejemplo: El primer segmento posible empieza en la
dirección
física 0. El segundo empieza en la dirección 2.
Esto es más complejo de lo que parece. Si tienes alguna duda, ya sabes...
Si le das vueltas a la idea, te darás cuenta que
diferentes combinaciones
de direcciones segmentadas dan una misma dirección física.
También se puede apreciar que los segmentos se pueden superponer unos a
otros, pueden ser idénticos, o pueden encontrarse en
partes totalmente
lejanas en la memoria.
Si llegados a este punto no comprendes el tema de los
segmentos, no sigas,
ya que te perderías. Dime qué no entiendes y lo
explicaré más
detalladamente.
Es todo por ahora.
Saludos.
AESOFT.