ASM
POR AESOFT
Corregido y pasado a HTML por dek_Oin
LECCIÓN
1:
CONOCIENDO
LA MAQUINA
Hola
a todos los futuros seguidores del curso de ensamblador de AESOFT.
Esta
primera lección va a ser sobre todo teórica. No se puede programar en
ensamblador sin tener un conocimiento más o menos profundo acerca de las
peculiaridades de la máquina que vamos a programar. Esto es obvio, ya que en
ensamblador tenemos un control total del sistema, por tanto, cuanto más sepamos
acerca de él más provecho podremos sacar del mismo, y mejores resultados
obtendremos.
En
primer lugar debemos saber con que‚ estamos trabajando, y no me refiero al
lenguaje en s¡, sino al ordenador en cuestión. Tendremos que conocer de que‚
partes consta, como se comunican entre s¡, etc. Esta parte teórica es casi
imprescindible para poder entender ciertas técnicas de programación.
Deciros
también que vamos a estudiar la PC en general, no distinguiremos entre
distintas familias de procesadores (8086,286,386,etc) ya que vamos a utilizar
ensamblador del 8086. En realidad es el ensamblador que yo utilizo. Por tanto,
aunque estemos programando sobre un 80386 o un 80486, desarrollaremos código
ejecutable para la familia 80x86 en general. Cualquier exposición que haga ser
válida para toda la familia PC.
Bueno...
Después de esta introducción, comencemos:
Una
PC es un ordenador o computador, como más os guste, compuesto principalmente
por procesador, chips de memoria, varios chips inteligentes o programables, y el
bus de datos y direcciones. Junto con todo esto, nos encontramos los periféricos
como son monitor, disqueteras, teclado, etc, que se comunican con el procesador.
Esto (la comunicación del procesador con periféricos) se ver más
adelante.
El
procesador:
Es
el chip que ejecuta los programas. El procesador o CPU, lleva a cabo una gran
variedad de cálculos, comparaciones numéricas y transferencias de datos como
respuesta a las peticiones de los programas que estén siendo ejecutados en
memoria. La CPU controla las operaciones básicas del ordenador enviando y
recibiendo señales de control, direcciones de memoria y datos de un lugar a
otro del ordenador a través de un grupo de 'sendas electrónicas' llamadas BUS.
Localizadas
a lo largo de este BUS están las puertas de entrada y salida (E/S en castellano
o I/O en inglés), las cuales conectan a la memoria y a los chips de apoyo al
bus. Los datos pasan a través de estas puertas de E/S mientras viajan desde y
hasta la CPU y otras partes del ordenador. Como os decía antes, trataremos el
procesador 8086, siendo válido todo lo que digamos para el resto de
procesadores de la familia PC.
El
procesador 8086 es un procesador de 16 bits. Esto quiere decir entre otras
cosas, que el procesador va a manipular en una sola operación datos de hasta 16
bits. Es decir, cuando transfiera datos a la memoria o los traiga desde ella, lo
podrá hacer de 16 bits en 16 bits. Aquí juega un papel decisivo el BUS
de datos, ya que es por él por donde circulan los datos en las transferencias.
Más detalles unas cuantas líneas más abajo.
El
procesador cuenta con una serie de registros usados para realizar las
operaciones de cálculo, y como almacenamiento de datos.
Para
que os hagáis una idea, un registro del procesador es algo as¡ como una zona
de memoria dentro del procesador donde se puede almacenar información, de forma
que el acceso a esta información es instantáneo, ya que no hay que utilizar el
bus de datos que conecta el procesador con la memoria para obtener dichos datos.
Estos
registros se dividen en 5 grupos, según sus funciones:
Registros
de datos: AX, BX, CX y DX
Se
usan para cálculo y almacenamiento de propósito general. Son utilizados por
los programas para realizar cálculos, as¡ como para transferir datos de una
posición de memoria a otra, ya que no se puede hacer de forma directa. Es
decir, que no podemos transferir un dato de la posición de memoria X a la
posición Y sin antes depositar ese dato temporalmente en un registro del
procesador.
Estos
registros tienen una longitud de 16 bits, pero podemos descomponerlos cuando nos
interese en un par de registros de 8 bits. Quedando de la forma siguiente:
AX
= AH + AL
Siendo
AX el registro de 16 bits, compuesto por la conjunción (que no la suma) del
registro AH de 8 bits (los 8 bits m s significativos o de más
a
la izquierda) y el registro AL de 8 bits (los 8 bits menos
significativos
o de m s a la derecha).
BX = BH + BL
CX
= CH + CL
DX
= DH + DL
Para
estos tres registros se aplica lo mismo que para el registro AX.
Cada
uno de estos registros tiene funciones especiales que es interesante conocer.
Por ejemplo el registro AX es el llamado acumulador, hace que muchas operaciones
tengan una forma más corta, ya que lo especifican implícitamente. Es decir,
que hay operaciones que actúan sobre el registro AX en particular. BX se suele
utilizar en muchas instrucciones como registro base, sobre todo en
transferencias de datos entre memoria y procesador. CX es el registro contador,
muchas instrucciones lo utilizan para hacer incrementos o decrementos automáticos,
para realizar bucles, etc. DX es el registro de datos, se suele utilizar para
operaciones de 32 bits, para almacenar los 16 bits (o palabra) más
significativos.
Registros
Índice: SI, DI, BP y SP
Se
utilizan para acceder a memoria cuando se establece el modo de direccionamiento
mediante indexación o con punteros.
SI
y DI indican el ¡índice fuente y destino respectivamente. BP y SP indican el
puntero base y el puntero de la pila respectivamente.
Más
adelante hablaremos de la pila (que es un tipo de datos estructurado).
Estos
4 registros son de 16 bits, y no pueden ser utilizados como registros dobles de
8 bits.
Registros
de Segmento: CS, DS, SS y ES
Estos
registros apuntan al principio de un bloque de 64 kb de memoria o segmento, de
ah¡ lo de la 'S' con la que finalizan todos los registros: CS: registro
segmento de código. Establece al rea donde se halla el programa en
ejecución.
DS:
registro segmento de datos. Especifica la zona donde el programa lee y escribe
los datos por defecto.
SS:
registro segmento de pila. Especifica el rea donde se encuentra la pila
del sistema.
ES:
registro segmento extra. Se utiliza como una extensión del segmento de datos.
Es decir, indica otro rea de datos aparte del especificado por DS.
Puntero de instrucción: IP
Su
longitud es de 16 bits como el resto de los registros. Indica la dirección de
la siguiente instrucción a ejecutar, y su valor es ajustado durante la ejecución
de la instrucción en curso. Esta dirección está en el área de 64 kb de
direcciones especificado por CS.
CS
e IP en conjunción conforman la dirección física real de la siguiente
instrucción a ejecutar. Más adelante detallaremos este asunto.
Registro FLAGS. O banderas de estado
Su
longitud es de 16 bits. Cada uno de estos bits contiene cierta información
booleano (verdadero o falso). Según el valor de cada uno de estos bits sea
1(verdadero) o 0(falso), informar del estado de alguna situación en
particular.
Dentro
del registro de FLAGS hay 7 bits que no se utilizan. Los nombres
de
los utilizados son: Of, Df, If, Tf, Sf, Zf, Af, Pf y Cf.
Estos
bits se clasifican en dos grupos:
A
Flags de estado (Cf, Af, Of, Zf, Pf y Sf): muestran el estado del procesador.
B
Flags de control ( Df, If, Tf): determinan como el procesador responder a
determinadas situaciones. El programador manipular estos bits para
controlar el modo de ejecución de algunas instrucciones.
A
continuación se muestra el significado de cada uno de los flags:
Cf:
Bit de Carry (acarreo), se activa (se pone a 1) si se produce acarreo en
una operación aritmética.
Pf:
Bit de paridad, se activa si el resultado de una operación tiene paridad
par, es decir, si el resultado tiene un número par de unos.
Af:
Bit de carry auxiliar, se activa si una operación aritmética produce
acarreo de peso 16.
Zf:
Bit de cero, se activa si una operación produce 0 como resultado. Suele
ser el m s utilizado (más consultado) por los programadores, por lo menos
por m¡ (AESOFT). Se utiliza para comparaciones de datos y para otras muchas
cosas como ciertos bucles, etc.
Sf:
Bit de signo, se activa si el bit m s significativo de un resultado
es 1. Por convención cuando se opera con números negativos, se utiliza el bit
de mayor peso para indicar el signo: si el bit es cero, entonces se trata de un
número positivo, si es 1, se trata de número negativo. Ya veremos todo esto m s
adelante.
Tf:
Bit trap o desvío. Si Tf=1, el procesador ejecuta las instrucciones. Una
a una bajo control del usuario. Se pone a 1 este bit para realiza depuraciones
del código que se está ejecutando. De esta forma se puede seguir el flujo del
programa.
If:
Bit de interrupción, si vale 1, las interrupciones están permitidas, y
si vale 0, no.
Df:
Se usa en las instrucciones que manipulan cadenas de bytes. Según
coloque el programador este bit, a '0' o a '1', las cadenas de bytes serán
tratadas en sentido de direcciones crecientes o decrecientes.
Of:
Bit de overflow, indica desbordamiento en una operación aritmética.
La
Memoria:
Los
chips de memoria se dedican meramente a almacenar la información hasta que se
necesita. El número y la capacidad de almacenamiento de estos chips que hay
dentro del ordenador determinan la cantidad de memoria que podremos utilizar
para los programas y los datos. Normalmente la memoria siempre se ha dividido en
dos tipos principales,
como
son la RAM y la ROM.
Supongo
que ya conocen esto, as¡ qué no entro en el tema. Si alguien tiene alguna
duda, que lo diga.
Pues
bien, en principio, nosotros vamos a trabajar con el rango de memoria 0 1048576,
es decir, vamos a trabajar con el primer Mb (megabyte). Existen técnicas para
tratar la memoria que hay en direcciones superiores a éstas, pero eso ya se verá
en otro momento.
Pues
bien, en ese Megabyte inicial, tenemos tanto RAM como ROM. La memoria RAM que es
la que usamos para almacenar tanto programas como datos empieza en las
direcciones bajas y llega hasta el inicio de la ROM. La ROM, evidentemente está
situada en las posiciones altas de memoria, y
Un
tema muy importante en el mundo del PC es la denominada barrera de los 640 K que
seguro habréis oído hablar.
Esto
quiere decir que aunque tengamos instalados 8 Megabytes en nuestro ordenador, sólo
podremos ejecutar nuestro programa en las primeras 640 k.
Para
poder acceder a los 7 Megabytes restantes debemos utilizar funciones especiales
de manejo de memoria extendida, expandida, etc. Pero bueno, eso no nos interesa
ahora en absoluto. Os remito al fichero MEMO.ZIP que podréis encontrar en el
BBS, en el cual,
un
usuario (PC-adicto) nos ofrece una exposición más amplia acerca de la memoria
del PC.
Chips
inteligentes:
Se
trata de chips de apoyo, de los que se sirve el procesador o el usuario. Estos
chips existen debido a que el procesador no puede controlar todo el ordenador
sin ayuda. Al delegar ciertas funciones de control a otros chips, le queda más
tiempo libre para atender a su propio trabajo. Estos chips de apoyo pueden ser
responsables de procesos tales como el flujo de información a través de la
circuitería interna (como el controlador de interrupciones y el controlador DMA)
y controlar el flujo de información de uno a otro dispositivo (como un monitor o
una unidad de disco) conectado al ordenador. En resumen, estos chips están ah¡
para librar de trabajo al procesador.
Bus
de direcciones:
El
bus de direcciones del PC utiliza 20 líneas de señal para transmitir las
direcciones de memoria y de los dispositivos conectados al bus. Como a través
de cada una de esas 20 líneas pueden viajar dos posibles valores(0 ¢ 1, es
decir, tensión alta o tensión baja), el ordenador puede especificar 2^20 (2
elevado a 20) direcciones. Es decir, puede direccionar 1 Megabyte. Estamos
hablando del 8086 con un bus de direcciones de 20 bits. Modelos superiores como
el 80386 o el Pentium direccionan muchísimo más, tanto como les permite su
bus: 32 bits en el caso del 386 y 64 bits en el caso del Pentium. Es decir, 2^32
y 2^64 direcciones respectivamente.
Bus
de datos:
El
bus de datos trabaja con el bus de direcciones para transportar los datos a través
del ordenador. Este bus de datos es de 16 bits, al igual que el tamaño de
registro. Aunque no tiene que
coincidir, como sucede con el procesador 8088, el cual tiene un tamaño de
registro de 16 bits y un bus de datos de 8 bits. Esto es as¡ por simple economía.
Por ahorrar costes. Claro que tiene su parte mala, y es que es más lento al
realizar
Bueno,
bueno, bueno... Todo esto que parece muy complicado es muy importante. No es lo
mismo programar sabiendo con qué‚ se trabaja que programar a ciegas. Muchas
veces es imprescindible recrear gráficamente ciertas instrucciones, para darse
cuenta de un fallo en el programa.
Venga,
ahora quiero que me contéis dudas que tenéis, aclaraciones, etc. Que la próxima
lección ya es más práctica. Pero hasta que no se tenga claro como funciona el
ordenador, no se puede hacer que funcione correctamente.
Lo
dicho, espero mensajes vuestros antes de la siguiente lección.
Un
saludo de AESOFT.