Arquitectura y programacién de un microprocesador de 16 bits (8086) 149
* Elaceso a una palabra de direccién par, que es el mas normal, requiere que A,= 0 y
BHE = 0.
# Sin embargo, el acceso a una palabra de direccién impar requiere 2 pasos; uno para
acceder al byte menos significativo y que, por estar en direccién impar, requerira que
A,~ 1 y BHE = 0, y otro paso para acceder al byte mas significativo que, por estar en
una posicién par, requeriré que A,= 0 y BHE = 1.
8.4. MODOS DE DIRECCIONAMIENTO
Hay ocho modos de direccionamiento para acceder a los datos de memoria que se
pueden utilizar en el 8086:
— Implicito.
— Inmediato.
— A registro.
— Directo.
— Indirecto.
— Indirecto por base.
— Indirecto por indice.
— Indexado respecto a una base.
Antes de pasar a ver con més detalle cada uno de los modos citados conviene
aprender la forma de representar las constantes numéricas en diferentes sistemas de
numeracién para que el microprocesador 8086 pueda entendernos.
Lo tinico que hay que tener en cuenta es que las cantidades numéricas iran seguidas
de la letra:
— B, si son binarias.
— O, si son octales.
— D 0 nada, si son decimales.
— H, si son hexadecimales.
Por ejemplo, las siguientes cantidades representan la misma constante numérica en
diferentes sistemas de numeracién:
— 10101018, en binario.
— 1250, en octal.
— 85D, o simplemente 85, en decimal.
— 55H, en hexadecimal.
Tambien existe la posibilidad, como en la mayoria de los lenguajes, de representar
constantes alfanumeéricas encerréndolas entre comillas simples, como, por ejemplo:
‘ABCD’, ‘FIN’, ‘H’, etc.; constantes que seran traducidas por el programa ensamblador a
sus equivalentes en ASCII, utilizando un byte para cardcter, como ya vimos en el Capi-
tulo 1.
Por ultimo, y para terminar con las consideraciones previas a los modos de direccio-
namiento, hay que decir que en la programaci6n del 8086 no vamos a trabajar con150 Lenguajes ensambladores
direcciones de memoria de forma explicita, como haciamos en el 6502, sino que lo
vamos a hacer con variables a las que el intérprete les asignaré la posicién de memoria
correspondiente. En realidad, y para hablar con propiedad, las variables no son mas que
desplazamientos que se sumarén normalmente y por defecto al registro de segmento de
datos (DS x 10H) para calcular la direccion real del dato; aunque, como veremos mas
adelante, también se puede indicar de forma explicita cualquier otro segmento.
= Direccionamiento implicito
Vamos a tener en el repertorio de instrucciones del 8086 un conjunto de instrucciones
que no necesitardn ir seguidas de ningdn operando por ir implicito con el c6digo de
operacion. Por ejemplo, AAA (ajuste ASCII para la suma), CLC (puesta a 0 del bit CF) y
muchas més.
= Direccionamiento inmediato
En este modo de direccionamiento, como ya sabemos, el operando se indica explicita-
mente. Por ejemplo:
— MOV AL, 142, que carga el registro AL con el valor decimal 142.
— ADD AH,1AH, que suma al registro AH la constante hexadecimal 1A.
= Direccionamiento a registro
En este tipo de direccionamiento lo operandos son los contenidos de los registros especi-
ficados en la instruccién. Por ejemplo:
— MOV AL,DL, que traslada el contenido del registro DL al AL.
— ADD AX,CX, que suma al registro AX el contenido del CX.
= Direccionamiento absolute o directo
Cuando estudiamos los modos de direccionamiento del 6502 vimos que los direcciona-
mientos absoluto y directo eran esencialmente el mismo, con la salvedad de que el
directo se referia a datos de la pagina 0 y el absoluto a datos de cualquier pagina. En el
8086 no se va a producir esta diferenciaci6n, de ahi que los conceptos absoluto y directo
coincidan.
Asi, por ejemplo, la instruccién MOV NUM8 cargaré la constante numérica 8
(direccionamiento inmediato) en la direccién resultante de sumar el desplazamiento
NUM al producto resultante de multiplicar por 10H (0 16D) el contenido del registro de
segmento DS; es decir, en la direccion DS x 10H + NUM. Otra forma de escribir la
instruccién seria: MOV DS:NUM,8.
Sin embargo, la instruccion MOV ES:NUM,8 no seria equivalente a la anteriorArquitectura y programacién de un microprocesador de 16 bits (8086) 151
porque, aunque el desplazamiento es el mismo (NUM), éste no se toma sobre el mismo
segmento de memoria. En la Figura 8.5 se puede apreciar de forma mas clara la diferen-
cia entre las dos instrucciones.
Memoria principal
ps
ss
ES
Vos. ro + wun } Seqmento de dates
Rogistros de wre
Figura 8.5. Direccionamiento absoluto,
Ves. 10H + num | Segmento extra
™ Direccionamiento indirecto
Este modo de direccionamiento es muy parecido al anterior. En este caso el operando, o
desplazamiento, se encuentra en uno de los registros indice o base (BX, BP, SI 0 DI) y se
indica encerrando entre corchetes el nombre del registro referido.
Por ejemplo: MOV [BX],CX llevard el contenido del registro CX (direccionamiento
a registro) a la direccién resultante de sumar el contenido del registro BX al resultado de
multiplicar por 10H el contenido del registro de segmento DS; es decir, a la direccién
DS x 10H + BX.
® Direccionamiento indirecto respecto a una base
Este tipo de direccionamiento es una especie de mezcla entre el directo y el indirecto, ya
que la posicién del dato 0, mejor dicho, el desplazamiento que nos va a dar la posicién del
dato con respecto al registro de segmento viene dado por el contenido de un registro
interno que hace de base, BX 0 BP, y un desplazamiento sobre esa base indicado de
forma indirecta normalmente; aunque a veces, y como veremos en el ejemplo siguiente,
de forma inmediata.
Por ejemplo, la instruccién MOV AX,[BX+8] llevard al registro AX (direcciona-
miento a registro) el contenido de la direccin resultante de la operacion:
DS x 10H + BX +8
Este direccionamiento es util cuando tenemos una tabla unidimensional, o vector,
en memoria en la que cada elemento esta formado por varios campos y en un momento152 Lenguajes ensambladores
dado se desea acceder a todos los campos del vector que representan una misma caracte-
ristica. Por ejemplo, supongamos que tenemos un conjunto de datos formado por los
nombres y las notas en tres asignaturas (Cobol, Ensamblador y RPG) de los 40 alumnos
de un curso, almacenados a partir de la posicién 1000H, como se indica en la Figu-
ra 8.6.
Direcciones (hex)
109F | NOTA-RPG
|
| it 1007 NOTA-RPG
als 1008 | NOTA-ENSAMBLADOR
1008 | NOTA-coBOL
1004 | NOMBRE
1003 | _NOTA-RPG
| a |ing 1002 | NOTA-ENSAMBLADOR
1001 | _NOTA-COBOL
NOMBRE
Memoria principal
Alumno 40.°
Alumno 2.°
BX — Base
3 Desplazamiento para
acceder a cada NOTA-RPG
Alumno 1.°
Figura 8.6. Direccionamiento indirecto.
Asi, si quisiéramos recorrer la tabla para acceder a cada una de las notas en RPG
para almacenarlas en la parte baja del acumulador, AL, y después procesarlas, tendria-
mos que hacer el siguiente algoritmo:Arquitectura y programacién de un microprocesador de 16 bits (8086) 153
CONTADOR < 0
BX < 1000H
Repetir
MOV AL,BX + 3]
Proceso
BX < BX+4
CONTADOR < CONTADOR + 1
hasta que CONTADOR = 40
= Direccionamiento indirecto con indice
Muy parecido al anterior, ya que el desplazamiento que nos da la direccién del dato
respecto al registro de segmento correspondiente (DS normalmente) viene dado por una
base, que sera una constante 0 una variable, y un desplazamiento con respecto a esa
base, que viene dado por el contenido de uno de los registros indice, SI o DI.
Por ejemplo, la instruccién ADD AX, [DI+8] sumara al registro AX (direcciona-
miento a registro) el contenido de la direccién resultante de la siguiente operaci6n:
DS x 10H + 8 + DI
Este direccionamiento puede ser titil para acceder a los datos de un vector simple
(un campo por componente). Para lo cual la base deberd apuntar a la posicion donde se
Direcciones {hex.)
1027 | NOMBRE
Desplazamiento (S)
1002
1001 | NOMBRE
Base———> 1000 | NOMBRE
Memoria principal
Alumno 40
Alumno 2
Alumno 1
Figura 8.7. Direccionamiento indirecto con indice.154 —_Lenguajes ensambladores
encuentre el primer elemento del vector, quedando el indice como variable para acceder
a la posicion o posiciones deseadas.
Por ejemplo, supongamos que tenemos un vector con los nombres de los 40 alum-
nos de una clase, almacenados a partir de la posicion 1000H, como se indica en la Figu-
ra8.7.
En estas condiciones, para acceder a los nombres de los 40 alumnos, Ilevarlos a
Ja parte baja del acumulador (AL) y procesarlos tendriamos que hacer el siguiente algo-
ritmo:
sI<-0
Repetir
MOV AL,SI + 1000H]
Proceso
Sl< Sl+1
hasta que SI = 28H (40 en decimal)
= Direccionamiento indexado respecto a una base
Este modo de direccionamiento es una combinacién del indirecto con indice y del
indirecto con respecto a una base. En este caso el desplazamiento que nos da la posicién
del dato con respecto al registro del segmento correspondiente viene dado por la suma
de los contenidos de un registro de base (BX o BP), de un registro de indice (DI 0 SI)
y, de forma opcional, un desplazamiento adicional, dado por una constante o una
variable.
Por ejemplo, la instruccisn ADD [BX+DI+NUM],AX sumara el contenido del
registro AX (direccionamiento a registro) al dato contenido en Ia direccién dada
por:
DS x 10H + BX + DI + NUM
Este tipo de direccionamiento es util cuando necesitamos acceder a una tabla bidi-
mensional 0 matriz en la que los accesos se tienen que realizar por medio de dos varia~
bles.
Por ejemplo, y continuando con el ejemplo de la Figura 8.6, supongamos que lo que
tenemos en memoria no son sélo los datos (nombre y nota en 3 asignaturas) de los 40
alumnos de una clase, sino los de las 20 clases de un colegio. Entonces, si en un momen-
to dado quisiéramos acceder a la nota de Ensamblador (dato 3.° de cada alumno) delArquitectura y programacién de un microprocesador de 16 bits (8086) 155
alumno n.°7 del curso 10.° y cargarla en el registro AL, tendriamos que hacer lo siguien-
te:
BX < 1000H_; direccién de comienzo de los datos
BX < BX +(09H * OAOH)
Sl<— 6H*4H
MOV AL [BX + SI +3]
8.5. PSEUDOINSTRUCCIONES O DIRECTIVAS
DEL LENGUAJE ENSAMBLADOR
Como vimos en el Capitulo 5, las pseudoinstrucciones son informaciones que se dan al
ordenador para hacer y facilitar la traduccién del programa a lenguaje maquina. Estas se
escriben junto al programa como si fuesen una instruccién més, pero no son traducidas
al cédigo maquina porque carecen de cddigo equivalente.
En el 6502 no vimos ninguna, ya que éstas varian segtin el tipo de traductor que se
utilice; por eso en los ejemplos tratamos de evitarlas con suposiciones del tipo: «suponer
que en la posicién de memoria tal tenemos el dato cuab», etc.
Sin embargo, en la programacién del 8086 no vamos a poder evitarlas tan facilmen-
te, por lo que vamos a estudiar las mas fundamentales e indispensables, que nos van a
permitir definir segmentos, variables, tablas, etc.
Tanto el conjunto de pseudoinstrucciones que vamos a ver a continuacién como el
repertorio de instrucciones del apartado proximo corresponden al lenguaje ensamblador
denominado ASM86, que es el mas conocido de los lenguajes de programacién
del 8086.
8.5.1. Definicién de segmentos
Ya vimos anteriormente cuando estudiamos el acceso a la memoria que el 8086 dispone
de 4 registros, denominados de segmento, a partir de los cuales se calcula la direccién
real o efectiva de los datos. También vimos que cada uno de estos segmentos contenia
un tipo concreto de informacién: cédigo, datos, Pita —_y extra.
Andlogamente, un programa va a estar formado por una serie de datos ¢ instruccio-
nes almacenados en la memoria agrupados en segmentos lgicos. Esto se consigue con la
pseudoinstruccion SEGMENT/ENDS (o SEGMENT STACK/ENDS para el segmento
de la pila), que indica el principio o el fin de un segmento logico.