                INTRODUCCION AL ASM: EL 8086 Y LA ARQUITECTURA PC
                =================================================

   En este segundo captulo del curso de ASM, veremos cmo difiere el 8086 de
la arquitectura ideal que vimos en el primer captulo. Despus, comenzaremos
a estudiar los registros del 8086.

   El 8086, que es el uP que llevan los compatibles PC (todos los uP de la
serie 80x86 de Intel, los NEC V20 y V30, el Cyrix486, los AMD... son
totalmente compatibles con el 8086, es decir, reconocen el mismo juego de
cdigos de operacin, aunque incluyan algunos - o muchos - ms), difiere
bastante del esquema que vimos en el captulo anterior.

   Lo primero es que los buses de direcciones y de datos tienen otra anchura:
20 bits para el bus de direcciones y 16 para el de datos. Cuando el uP genera
una lectura de memoria de la direccin x, se leen los bytes de la direccin (x)
y de la direccin (x+1), componindose con estos la palabra de 16 bits que se
enva al uP. En el 8086 y todos los uP Intel (y el Z80, y muchos otros), el
byte de la dir. (x) se usa para los 8 bits desde D0 hasta D7, y el de la dir.
(x+1) para los bits desde D8 hasta D15. Este ordenamiento de bytes se suele
denominar 'ordenamiento Intel' (adivinad por qu...), mientras que otros uP
como el Motorola MC68000 y los de su serie (usados en los Mac) usan el
'ordenamiento Motorola', en el que los bytes de una palabra (con una palabra
nos referimos al conjunto de dos bytes)  se almacenan al reves en memoria.

   El 8088 se diferenciaba del 8086 bsicamente en que el bus de datos del uP
era de 8 bits, por lo que las lecturas de 16 bits deban realizarse en dos
pasos. A nivel de programacin esto no se percibe, ya que una instruccin que
produzca una lectura de 16 bits se ejecuta igual pero tarda el doble, mientras
que la circuitera externa debe ser algo ms complicada. Por lo dems, el 8088
lo consideraremos idntico al 8086 y hablaremos nicamente de ste ltimo. Las
VGA, por ejemplo, son dispositivos que aaden memoria a la propia del ordena-
dor, de manera que decir que una VGA es de 8 bits o de 16 indica si los accesos
a memoria de 16 bits se hacen en dos pasos, como en los ordenadores con 8088, o
en uno. Queda claro por qu el mismo programa corre mucho ms rpido en una
VGA de 16 bits que en una de 8, siempre que el programa haga accesos a memoria
de palabra en palabra.

   El problema que se present a los diseadores del 8086 fue que los registros
internos del uP (el IP y muchos ms que estudiaremos detalladamente ms adelan-
te) deban ser de 16 bits, probablemente por limitaciones de diseo, mientras
que las direcciones que se envan por el bus de direcciones (y valga la redun-
dancia) deban ser de 20 bits. Para componer una direccin de memoria completa
son necesarios otros 4 bits adems de los 16 de cada registro, ya que si estos
cuatro bits se ponen siempre al mismo valor slo tendremos acceso a 64K de
memoria. La solucin que se adopto ha venido limitando la accesibilidad de
memoria de los PCs desde entonces, y es la razn de que ahora mismo existan
cosas como la memoria extendida, la expandida, y otras peculiaridades que
suponen un gran handicap para los programas que corren en PCs frente a otros
ordenadores como los Mac.

   La solucin pasaba por aadir en el interior del micro varios registros de
16 bits llamados 'registros de segmento'. Son cuatro en el 8086 y el 286, y 2
ms en el 386 y superiores. Aqu nos limitaremos a usar los del 8086, pero el
uso de los otros es idntico en los 386+. La direccin completa de 20 bits se
forma a partir de un registro de segmento, que se elige en cada momento, y un
registro de 16 bits que se denomina 'desplazamiento' u 'offset'. Una de las
posibilidades hubiese sido tomar los 4 bits bajos del registro de segmento y
aadirles detrs los 16 del offset. As compondramos una direccin completa:

                        SEGMENTO     |    OFFSET
                 0000 0000 0000 1010   0101 1111 0000 1010
                                \      dir. completa     /
                                 1010 0101 1111 0000 1010   (20 bits)

   De esta forma, los 4 bits bajos del segmento determinaran uno de los 16
bancos de 64K contenidos en un megabyte de memoria (el espacio direccionable
con 20 bits), y el offset determinara la direccin en concreto a partir de la
direccin base de este segmento. Si el segmento fuera 0000h accederamos a los
64K ms bajos del megabyte, si fuera 0001h accederamos a los 64K siguientes, y
as hasta un valor de segmento de 000Fh con el que accederamos a los ltimos
64K. As, haciendo un smil en el que una carta de una baraja represente el
espacio de memoria accesible para cada valor de segmento, nuestra baraja (el
conjunto de todos los segmentos) est formada por 16 cartas, y est dispuesta
con cada carta junto a la otra sin superponerse, de manera que con todas las
cartas podemos acceder al mega completo de memoria. Con esta disposicin a cada
posicin de memoria slo puede acceder por medio de una carta, y por tanto el
par segmento:offset que determina una direccin de memoria concreta es nico.

   Pero ya que los registros de segmento se hicieron de 16 bits, se eligi otra
forma de hacerlo de manera que se aprovechan totalmente los 16 bits del
segmento: lo que se hace para generar la direccin completa es desplazar el
segmento cuatro bits hacia la izquierda, rellenando los 4 bits de la derecha
con ceros, y sumarle al valor de 20 bits resultante el offset. El desplaza-
miento a la izquierda equivale a multiplicar por 16 o aadir un cero a la
derecha en hexadecimal:

                                   /  valor de seg.  \
               16d x  SEGMENTO     0000 0000 0000 1010 0000 <- 4 bits 'extra'
                      OFFSET            0101 1111 0000 1010
                     ---------------------------------------
                   DIRECCION REAL  0000 0101 1111 1010 1010  (20 bits)

   As, el valor de segmento determina una direccin base (la formada por su
valor con los cuatro bits a cero), a partir de la cual el offset especifica
cunto hay que moverse para hallar la direccin en concreto. Si meditamos un
poco sobre esto, podemos apreciar que cada segmento de 64K (que es el espacio
direccionable variando el offset y dejando el segmento fijo) se superpone con
otros segmentos. Ahora, volviendo al smil de la baraja, tenemos 64K (64*1024)
cartas, correspondientes a los 64K posibles diferentes valores de segmento.
Tambin ahora podemos acceder al mega completo, pero las cartas estn dispues-
tas no una al lado de la otra, sino que cada carta est dispuesta 16 posiciones
ms a la derecha (o ms arriba) que la anterior, de manera que se superpone a
la anterior casi en toda su extensin. Pero, como ya hemos dicho, la anchura
total de las cartas (la memoria total accesible) sigue siendo de un megabyte.
As, una misma direccin real se puede generar a partir de diferentes valores
de segmento y offset. Por ejemplo, veamos la posicin de memoria absoluta 17d
o 00011h. Esta direccin se puede especificar como valor de segmento 0 y offset
17d (0000:0011h), pero podemos apreciar que el par 0001:0001 tambin representa
la misma direccin absoluta. Para especificar una direccin por medio del seg-
mento y el offset se suele poner el valor del segmento (sin los cuatro bits que
se aaden a la derecha), dos puntos, y el valor de offset. Como segundo ejem-
plo, las direcciones 0040h:0000 y 0000:0400h son totalmente equivalentes y
ambas referencian la misma direccin absoluta de memoria, la 00400h o 1024d.

   Para ir entrando un poco en cmo es el 8086 en concreto, recordaremos un
registro que ya mencionamos: el IP o 'Instruction Pointer', que contiene la
direccin de la siguiente instruccin a ejecutar. Este registro es de 16 bits,
por lo que necesitamos un registro de segmento para componer la direccin
completa de la siguiente instruccin. El segmento 'CS' o 'Code Segment' es el
registro con el que el uP compone la direccin completa de la siguiente
instruccin a recoger y ejecutar.

   En un libro de programacin en ASM tradicional, ahora veramos el conjunto
completo de registros del 8086, la funcin de cada uno, etc... Estos libros,
adems de para el aprendizaje, estn pensados como referencia para el progra-
mador que ya conoce el micro o que ya conoce ASM de algn otro micro. Pero ya
que esto es un curso pensado para gente que nunca antes haya tenido contacto
con el lenguaje ensamblador, se seguir otro orden: veremos primero algunos de
los registros, cuya funcin se puede comprender con los conocimientos adquiri-
dos hasta ahora, y a medida que se vayan introduciendo conceptos como la pila,
los saltos condicionales, etc... veremos el resto de los registros.

   Todos los micros, incluyendo el menos potente, suelen tener un registro que
se utiliza de forma preferente para las operaciones aritmticas y lgicas.
Algunos micros, como el Z80, tienen algunas instrucciones que slo pueden
ejecutarse con este registro. Este registro se suele denominar 'acumulador',
y en el 8086 toma el nombre simblico de 'AX'. El 8086, adems del AX,
incorpora otros tres registros denominados 'de propsito general', con los que
tambin se pueden hacer algunas operaciones aritmticas. Pero, por ejemplo, las
multiplicaciones o divisiones slo se pueden hacer con el AX. Los otros
registros tambin presentan peculiaridades, instrucciones que operan sobre un
registro determinado, pero las iremos viendo sobre la marcha. Estos otros tres
registros se representan mediante los nombres 'BX', 'CX' y 'DX', y son todos
de 16 bits.

   Para componer direcciones de memoria, adems del CS que se usa principal-
mente para complementar al IP, existen otros registros de segmento. Por el
momento describiremos dos de los otros tres que existen, el 'DS' (Data
Segment) y el 'ES' (Extra Segment). Cuando leemos datos de la memoria, dando
la direccin de la que leer por medio de un registro, por defecto se construye
la direccin completa usando el DS, aunque se puede especificar en la instruc-
cin si se quiere usar el ES o el CS en su lugar.

   En el siguiente captulo veremos la primera instruccin de ASM, la ms
usada, la instruccin 'MOV'. Y comentaremos algunas cosillas de cmo empezar
a experimentar con el ASM sin ms que el DEBUG del MS-DOS.

   Salut!!! :-)

   Jon