You are on page 1of 77

Lenguaje Ensamblador

INTRODUCCIÓN.

El documento que esta visualizando tiene la función primordial de introducirlo a la


programación en lenguaje ensamblador, y está pensado en aquellas personas que nunca
han trabajado con este lenguaje y probablemente con ningún otro.

El texto se enfoca completamente hacia las computadoras que operan con procesadores
de la familia x86 de Intel y, considerando que el ensamblador basa su funcionamiento en
los recursos internos del procesador, los ejemplos descritos no son compatibles con
ninguna otra arquitectura.

Se estructura la información en forma de unidades para permitir el fácil acceso a cada uno
de los típicos y facilitar el seguimiento del texto.

En la sección introductoria se mencionan algunos de los conceptos elementales acerca de


los sistemas de cómputo así como del ensamblador mismo, y continúa con el texto
propiamente dicho.

M. D. O. H. Sonia Alvarado Mares


1
Lenguaje Ensamblador

UNIDAD I.
FUNDAMENTOS
1.1 INTRODUCCIÓN.
1.1.1 Generalidades del lenguaje ensamblador.
1.1.2 Escalabilidad de los microprocesadores
1.1.3 Tipos de lenguajes ensambladores
1.1.4 Clasificación de memorias
1.1.5 Unidades de entrada/salida

1.2 EL MICROPROCESADOR.
1.2.1 Buses
1.2.2 Registros
1.2.3 Modos de direccionamiento

1.3 INTERRUPCIONES.
1.3.1 Hardware
1.3.2 Software

1.4 ESTRUCTURA DE UN PROGRAMA EN


ENSAMBLADOR.
1.4.1 Data segment
1.4.2 Stack segment
1.4.3 Code segment
1.4.4 Instrucciones del programa
1.4.5 Directivas

1.5 PROCEDIMIENTO DE ENSAMBLE, ENLACE Y


EJECUCIÓN.

1.6 ENTORNO DE PROGRAMACIÓN.

1.1 INTRODUCCIÓN.
1.1.1 Generalidades del lenguaje ensamblador.

M. D. O. H. Sonia Alvarado Mares


2
Lenguaje Ensamblador

¿Qué es ensamblador y para qué sirve?

Cuando se empezaron a utilizar símbolos nemotécnicos, se escribieron programas para


traducir automáticamente los programas escritos en lenguaje ensamblador a lenguaje
máquina. A estos programas traductores se les llamo ensambladores.

La entrada para un ensamblador es un programa fuente escrito en lenguaje ensamblador.


La salida es un programa objeto, escrito en lenguaje de máquina. El programa objeto
incluye también la información necesaria para que el cargador pueda preparar el
programa objeto para su ejecución.

Para evitar confusiones, de aquí en adelante llamaremos lenguaje ensamblador al


conjunto de nemotécnicos y a las reglas para su manejo. Al programa que traduce un
programa objeto a partir de un programa escrito en lenguaje ensamblador lo llamaremos
ensamblador.

Motivos para utilizarlo.

• Rapidez: Como el programador directamente selecciona las instrucciones que se


ejecutan en el programa, el programa final queda mas optimizado que un
programa generado por un compilador.

• Mayor control de la computadora:


computadora Un programa puede accesar directamente
cualquier componente y periférico de la computadora.

• Independencia del lenguaje:


lenguaje No depende de librerías o del lenguaje mismo para
realizar una tarea específica. Lenguajes como el Basic limitan al programador a lo
que el lenguaje puede hacer.

• La mayoría de las computadoras pueden ensamblar: Los recursos necesarios para


ensamblar un programa son mucho menores que los compiladores o interpretes.
El ensamblador generalmente es más rápido ensamblando un programa que un
compilador generando un archivo ejecutable.

Motivos para no utilizarlo.


utilizarlo.

Desafortunadamente, también existen motivos para no crear los programas con


ensamblador.

• Dependencia del hardware:


hardware El código se hace en extremo dependiente del
microprocesador, de los dispositivos, de los controladores, etc. Este punto será
analizado con más detenimiento en dependencias de hardware.

• Mayor tiempo de codificación:


codificación El número de líneas de un programa hecho en
ensamblador es mayor a uno hecho en un lenguaje de alto nivel (por ejemplo:
Función en C puede realizar varias decenas o centenas de instrucciones del
microprocesador).

M. D. O. H. Sonia Alvarado Mares


3
Lenguaje Ensamblador

• Comprensión mas profunda de la computadora:


computadora Entender un lenguaje de alto nivel
es generalmente más sencillo que el ensamblador. Comprender ensamblador
requiere conocimientos más exactos sobre el funcionamiento interno de la
computadora.

• Errores más frecuentes en el programa:


programa El evitar un error o encontrar alguno que
ya exista es difícil. Las herramientas para este caso (como el CodeView y el
TurboDebbuger) ayudan en gran medida a ver lo que esta ocurriendo en la
maquina, pero no localizan los errores.

Entonces, ¿Cuándo utilizo ensamblador y cuándo no?

Depende del programa a desarrollar. Si el programa debe controlar en gran medida los
componentes internos de la computadora o debe ser lo suficientemente veloz, entonces
es recomendable utilizarlo. Si se requiere un sistema grande y no se dispone de mucho
tiempo para entregarlo, entonces es mejor juntar un lenguaje de alto nivel con
ensamblador (las funciones básicas del programa realizarlas en ensamblador, y el
programa en general codificarlo con el lenguaje de alto nivel).

Importancia del lenguaje ensamblador.

La importancia del lenguaje ensamblador radica principalmente que se trabaja


directamente con el microprocesador; por lo cual se debe de conocer el funcionamiento
interno de este, tiene la ventaja de que en el se puede realizar cualquier tipo de
programas que en los lenguajes de alto nivel no lo pueden realizar. Otro punto sería que
los programas en ensamblador ocupan menos espacio en memoria.

Ventajas del Lenguaje Ensamblador.

• Velocidad .- Como trabaja directamente con el microprocesador al ejecutar un


programa, pues como este lenguaje es el mas cercano a la máquina la
computadora lo procesa mas rápido.

• Eficiencia de tamaño.-
tamaño Un programa en ensamblador no ocupa mucho espacio en
memoria porque no tiene que cargan librerías y demás como son los lenguajes de
alto nivel

• Flexibilidad .- Es flexible porque todo lo que puede hacerse con una máquina,
puede hacerse en el lenguaje ensamblador de esta máquina; los lenguajes de alto
nivel tienen en una u otra forma limitantes para explotar al máximo los recursos de
la máquina. O sea que en lenguaje ensamblador se pueden hacer tareas
específicas que en un lenguaje de alto nivel no se pueden llevar acabo porque
tienen ciertas limitantes que no se lo permite.

M. D. O. H. Sonia Alvarado Mares


4
Lenguaje Ensamblador

Desventajas del Lenguaje Ensamblador.

• Tiempo de programación .- Como es un lenguaje de bajo nivel requiere más


instrucciones para realizar el mismo proceso, en comparación con un lenguaje de
alto nivel. Por otro lado, requiere de más cuidado por parte del programador, pues
es propenso a que los errores de lógica se reflejen más fuertemente en la
ejecución.

• Programas fuentes
fuentes grandes .- Por las mismas razones que aumenta el tiempo,
crecen los programas fuentes; simplemente requerimos más instrucciones
primitivas para describir procesos equivalentes. Esto es una desventaja porque
dificulta el mantenimiento de los programas, y nuevamente reduce la productividad
de los programadores.

• Peligro de afectar recursos inesperadamente .- Que todo error que podamos


cometer, o todo riesgo que podamos tener, podemos afectar los recursos de la
máquina, programar en este lenguaje lo más común que pueda pasar es que la
máquina se bloquee o se reinicialice. Porque con este lenguaje es perfectamente
posible (y sencillo) realizar secuencias de instrucciones inválidas, que
normalmente no aparecen al usar un lenguaje de alto nivel.

• Falta de portabilidad.-
portabilidad Porque para cada máquina existe un lenguaje ensamblador;
por ello, evidentemente no es una selección apropiada de lenguaje cuando
deseamos codificar en una máquina y luego llevar los programas a otros sistemas
operativos o modelos de computadoras.

Uso y aplicación del lenguaje ensamblador.

El uso del lenguaje ensamblador no es para la gente común y corriente, sino para
profesionistas en el área de computación que están obligados a conocer este lenguaje, ya
que proporciona una serie de características que no se pueden encontrar en los lenguajes
de alto nivel. Algunas de estas características son:

• Se puede acceder a cualquier localidad de la memoria RAM sin ninguna


restricción.
• Se pueden programar virus, debido a que se tiene un acceso total a casi todo el
hardware de la computadora vía interrupciones de software.
• Se pueden programar Drivers de cualquier dispositivo.
• Se puede acceder directamente a los registros internos del CPU.
• Se puede acceder directamente a los dispositivos de entrada y/o salida.

M. D. O. H. Sonia Alvarado Mares


5
Lenguaje Ensamblador

• Los programas objeto generados a traés del ensamblador son mas veloces que
los generados en cualquier otro lenguaje, debido a que una instrucción en
ensamblador corresponde a una instrucción en lenguaje máquina.

El lenguaje ensamblador se utiliza para las siguientes aplicaciones:

• Sistemas embebidos: impresoras, cámaras, autos, juguetes, etc.


• Industria y manufactura: adquisición datos y control, eg robots.
• Transporte y aeronáutica: barcos, aviones, sondas espaciales, etc.
• Graficación, multimedia, cine y videojuegos.
• Procesamiento de señales, voz e imágenes.
• Armamento y defensa.

M. D. O. H. Sonia Alvarado Mares


6
Lenguaje Ensamblador

1.1.2 Escalabilidad de los microprocesadores.

Introducción.

El microprocesador es uno de los logros más sobresalientes del siglo XX. Esas son
palabras atrevidas, y hace un cuarto de siglo tal afirmación habría parecido absurda. Pero
cada año, el microprocesador se acerca más al centro de nuestras vidas, forjándose un
sitio en el núcleo de una máquina tras otra. Su presencia ha comenzado a cambiar la
forma en que percibimos el mundo e incluso a nosotros mismos. Cada vez se hace más
difícil pasar por alto el microprocesador como otro simple producto en una larga línea de
innovaciones tecnológicas.

Ninguna otra invención en la historia se ha diseminado tan aprisa por todo el mundo o ha
tocado tan profundamente tantos aspectos de la existencia humana. Hoy existen casi
15,000 millones de microchips de alguna clase en uso (el equivalente de dos
computadoras poderosas para cada hombre, mujer y niño del planeta). De cara a esa
realidad, ¿quién puede dudar que el microprocesador no sólo esta transformando los
productos que usamos, sino también nuestra forma de vivir y, por último, la forma en que
percibimos la realidad?

No obstante que reconocemos la penetración del microprocesador en nuestras vidas, ya


estamos creciendo indiferentes a la presencia de esos miles de máquinas diminutas que
nos encontramos sin saberlo todos los días. Así que, antes de que se integre de manera
demasiado imperceptible en nuestra diaria existencia, es el momento de celebrar al
microprocesador y la revolución que ha originado, para apreciar el milagro que es en
realidad cada uno de esos chips de silicio diminutos y meditar acerca de su significado
para nuestras vidas y las de nuestros descendientes.

¿Que es un microprocesador?

El microprocesador es la parte de la computadora diseñada para llevar acabo o ejecutar


los programas. Este viene siendo el cerebro de la computadora, el motor, el corazón de
esta máquina. Este ejecuta instrucciones que se le dan a la computadora a muy bajo nivel
haciendo operaciones lógicas simples, como sumar, restar, multiplicar y dividir. El
microprocesador, o simplemente el micro, es el cerebro del ordenador. Es un chip, un tipo
de componente electrónico en cuyo interior existen miles (o millones) de elementos
llamados transistores, cuya combinación permite realizar el trabajo que tenga
encomendado el chip.

Evolución del microprocesador.

El microprocesador es un producto de la computadora y con tecnología semiconductora.


Se eslabona desde la mitad de los años 50's; estas tecnologías se fusionaron a principios
de los años 70`'s, produciendo el llamado microprocesador.

M. D. O. H. Sonia Alvarado Mares


7
Lenguaje Ensamblador

La computadora digital hace cálculos bajo el control de un programa. La manera general


en que los cálculos se han hecho es llamada la arquitectura de la computadora digital. Así
mismo la historia de circuitos de estado sólido nos ayuda también, porque el
microprocesador es un circuito con transistores o microcircuito LSI (grande escala de
integración), para ser más preciso.

El mapa de la figura 1.1, mostrada al final de esta sección, muestra los sucesos
importantes de éstas dos tecnologías que se desarrollaron en las últimas cinco décadas.
Las dos tecnologías iniciaron su desarrollo desde la segunda guerra mundial; en este
tiempo los científicos desarrollaron computadoras especialmente para uso militar.
Después de la guerra, a mediados del año de 1940 la computadora digital fue
desarrollada para propósitos científicos y civiles.

La tecnología de circuitos electrónicos avanzó y los científicos hicieron grandes progresos


en el diseño de dispositivos físicos de estado Sólido. En 1948 en los laboratorios Bell
crearon el Transistor.

En los años 50's, aparecen las primeras computadoras digitales de propósito general.
Éstas usaban tubos al vacío (bulbos) como componentes electrónicos activos. Tarjetas o
módulos de tubos al vacío fueron usados para construir circuitos lógicos básicos tales
como compuertas lógicas y flip-flops (celda donde se almacena un bit). Ensamblando
compuertas y flip-flops en módulos, los científicos construyeron la computadora (la lógica
de control, circuitos de memoria, etc.). Los bulbos también formaron parte de la
construcción de máquinas para la comunicación con las computadoras. Para el estudio de
los circuitos digitales, en la construcción de un circuito sumador simple se requiere de
algunas compuertas lógicas.

La construcción de una computadora digital requiere de muchos circuitos o dispositivos


electrónicos. El principal paso tomado en la computadora fue hacer que el dato fuera
almacenado en memoria como una forma de palabra digital. La idea de almacenar
programas fue muy importante.

La tecnología de los circuitos de estado sólido evolucionó en la década de los años 50's.
El uso del material silicio de bajo costo y con métodos de producción masiva, hicieron al
transistor ser el más usado para el diseño de circuitos. Por lo tanto el diseño de la
computadora digital fue un gran avance del cambio para remplazar al tubo al vacío (bulbo)
por el transistor a finales de los años 50's.

A principios de los años 60's, el arte de la construcción de computadoras de estado sólido


se incrementó y surgieron las tecnologías en circuitos digitales como: RTL (Lógica
Transistor Resistor), DTL (Lógica Transistor Diodo), TTL (Lógica Transistor Transistor),
ECL (Lógica Complementada Emisor).

M. D. O. H. Sonia Alvarado Mares


8
Lenguaje Ensamblador

Figura 1.1 Sucesos importantes de las tecnologías.

A mediados de los años 60's se producen las familias de lógica digital, dispositivos en
escala SSI y MSI que corresponden a pequeña y mediana escala de integración de
componentes en los circuitos de fabricación. A finales de los años 60's y principios de los
años 70's surgieron los LSI (gran escala de integración). La tecnología LSI fue haciendo
posible más y más circuitos digitales en un circuito integrado. Pero pocos circuitos LSI
fueron producidos, los dispositivos de memoria fueron un buen ejemplo.

Las primeras calculadoras electrónicas requerían de 75 a 100 circuitos integrados.


Después se dio un paso importante en la reducción de la arquitectura de la computadora
a un circuito integrado simple, resultando un circuito que fue llamado el microprocesador.

El primer microprocesador fue el Intel 4004, producido en 1971. Se desarrolló


originalmente para una calculadora, y resultaba revolucionario para su época. Contenía
2.300 transistores en un microprocesador de 4 bits que sólo podía realizar 60.000
operaciones por segundo.

El primer microprocesador de 8 bits fue el Intel 8008, desarrollado en 1979 para su


empleo en terminales informáticos. El Intel 8008 contenía 3.300 transistores. El primer
microprocesador realmente diseñado para uso general, desarrollado en 1974, fue el Intel
8080 de 8 bits, que contenía 4.500 transistores y podía ejecutar 200.000 instrucciones por
segundo. Los microprocesadores modernos tienen una capacidad y velocidad mucho
mayores. Entre ellos figuran el Intel Pentium Pro, con 5,5 millones de transistores; el

M. D. O. H. Sonia Alvarado Mares


9
Lenguaje Ensamblador

UltraSparc-II, de Sun Microsystems, que contiene 5,4 millones de transistores; el


PowerPC 620, desarrollado conjuntamente por Apple, IBM y Motorola, con 7 millones de
transistores, y el Alpha 21164A, de Digital Equipment Corporation, con 9,3 millones de
transistores.

El Microprocesador.

El microprocesador tiene una arquitectura parecida a la computadora digital. En otras


palabras, el microprocesador es como la computadora digital porque ambos realizan
cálculos bajo un programa de control. Consiguientemente, la historia de la computadora
digital nos ayudará a entender el microprocesador.

El microprocesador hizo posible la manufactura de poderosas calculadoras y de muchos


otros productos. El microprocesador utiliza el mismo tipo de lógica que es usado en la
unidad procesadora central (CPU) de una computadora digital. El microprocesador es
algunas veces llamado unidad microprocesadora (MPU). En otras palabras, el
microprocesador es una unidad procesadora de datos.

En un microprocesador podemos diferenciar diversas partes:

1. El encapsulado: es lo que rodea a la oblea de silicio en si, para darle consistencia,


impedir su deterioro (por ejemplo, por oxidación por el aire) y permitir el enlace con
los conectores externos que lo acoplaran a su zócalo a su placa base.

2. La memoria caché: es una memoria ultrarrápida que emplea el micro para tener a
mano ciertos datos que prediciblemente serán utilizados en las siguientes
operaciones sin tener que acudir a la memoria RAM reduciendo el tiempo de
espera. Por ejemplo: en una biblioteca, en lugar de estar buscando cierto libro a
través de un banco de ficheros de papel se utiliza las computadora, y gracias a la
memoria caché, obtiene de manera rápida la información. Todos los micros
compatibles con PC poseen la llamada caché interna de primer nivel o L1; es decir,
la que está más cerca del micro, tanto que está encapsulada junto a él. Los micros
más modernos (Pentium III Coppermine, Athlon Thunderbird, etc.) incluyen también
en su interior otro nivel de caché, más grande aunque algo menos rápida, la caché
de segundo nivel o L2.

3. Coprocesador Matemático: o correctamente la FPU (Unidad de coma flotante).


Que es la parte del micro especializada en esa clase de cálculos matemáticos,
antiguamente estaba en el exterior del micro en otro chip. Esta parte esta
considerada como una parte "lógica" junto con los registros, la unidad de control,
memoria y bus de datos.

4. Los registros: son básicamente un tipo de memoria pequeña con fines especiales
que el micro tiene disponible para algunos usos particulares. Hay varios grupos de
registros en cada procesador. Un grupo de registros esta diseñado para control del
programador y hay otros que no son diseñados para ser controlados por el
procesador pero que CPU los utiliza en algunas operaciones en total son treinta y
dos registros.
M. D. O. H. Sonia Alvarado Mares
10
Lenguaje Ensamblador

5. La memoria: es el lugar donde el procesador encuentra sus instrucciones de


programa y sus datos. Tanto los datos como las instrucciones están almacenados
en memoria, y el procesador los toma de ahí. La memoria es una parte interna de la
computadora y su función esencial es proporcionar un espacio de trabajo para el
procesador.

6. Puertos: es la manera en que el procesador se comunica con el mundo externo. Un


puerto es parecido a una línea de teléfono. Cualquier parte de la circuitería de la
computadora con la cual el procesador necesita comunicarse, tiene asignado un
número de puerto que el procesador utiliza como un numero de teléfono para llamar
al circuito o a partes especiales.

Existen características fundamentales que son esenciales para identificar un


microprocesador, a parte del nombre que se le dan y marca o compañía por la que fue
fabricada. Los cuales son:

• Su ancho de bus (medido en bits).

• La velocidad con que trabajan (medida en hertzios): existen dos tipo de


velocidades de los micros hoy en día, velocidad interna la velocidad a la que
funciona el micro internamente (200, 333, 450... MHz); y velocidad externa o del
bus o también "velocidad del FSB"; la velocidad a la que se comunican el micro y
la placa base, para poder abaratar el precio de ésta. Típicamente, 33, 60, 66, 100
ó 133 MHz.

Microprocesadores Antiguos.

Tal como está el mundo, podríamos decir que cualquiera que tenga más de un mes en el
mercado. De todas formas, aquí vamos a suponer antiguo a todo micro que no sea un
Pentium o similar (K5, K6, 6x86, Celeron...)

8088 / 8086.

En 1975 Intel decidió ponerse manos a la obra para construir su primer micro de 16 bits
que salió al mercado en 1978. Se trataba del 8086, que definió el inicio de su gama de
productos más famosa, la familia de microprocesadores x86.

La longitud de los registros del 8086 era de 16 bits (de ahí su denominación de 16 bits),
había versiones que funcionaban a 4.77 y 8 MHz, tenía un bus de datos de 16 bits y un
bus de direcciones de 20 bits, lo que le permitía acceder a un máximo de memoria de 1
Mb según el cálculo 2 elevado a 20.

8088.

Seguidamente, en 1979, Intel sacó el 8088, que en contra de lo que podamos pensar no
es mejor que el 8086. La diferencia era sustancial; el bus de datos era de 8 bits (la mitad).
Este paso hacia atrás estuvo provocado por el estado de la industria de la época. Utilizar

M. D. O. H. Sonia Alvarado Mares


11
Lenguaje Ensamblador

un bus de datos de 16 bits suponía forzar al mercado a desarrollar para 16 bits lo que
implicaba un incremento en los costes de desarrollo de controladores de periféricos y
memorias. El síntoma fue que Intel se había adelantado a su época.

Los japoneses, aprovechando la ocasión y dando fe a su fama de copiones fabricaron


unos clónicos de los 8086 y 8088. Fue NEC la que, por procedimientos de ingeniería
inversa, sacó el diseño de estos micros y creó sus modelos V20 y V30, que
incrementaban el rendimiento respecto a los de Intel en un 10–30 por ciento. Como se
pueden imaginar Intel demandó a NEC, pero perdió el juicio. La Justicia determinó que el
microcódigo del chip podía registrarse pero Intel no había marcado en el chip el símbolo
del copyright, con lo cual perdía los derechos de copia.

Se encuentra un error de diseño en el 8088 que afecta a la gestión de interrupciones y al


registro de pila SS (Stack Segment).

80C86, 80C88, 80186 y 80188.

Intel fabricó variaciones de estos modelos, sacando al mercado los 80C86, 80C88, 80186
y 80188 cuyas modificaciones fueron el ahorro de energía en las versiones C para su
instalación en portátiles, y el rediseño interno para la optimización en las versiones 1.

80286.

En 1984 aparece el 80286 como base para una nueva generación de ordenadores de
IBM, el IBM AT (Advanced Technology). Supone un nuevo salto tecnológico. Además de
incrementar el bus de direcciones de 20 bits a 24, lo que permitía acceder hasta los 16 Mb
de RAM, se incrementaba la velocidad, llegando a ser hasta un 25 por ciento más rápidos
que los 8086 y 8088 originales.

La novedad más importante que se introdujo fue la gestión de memoria virtual. La


memoria virtual es una extensión de memoria en disco (o dispositivo de almacenamiento
secundario) añadida a la memoria física instalada. Así, el 80286 es capaz de tratar hasta
un total de 1 Gb, desglosado en 16 Mb de memoria física más 1008 Mb de memoria
virtual. La memoria virtual solamente la utilizan los programas que están preparados para
ello.

Aparece también un nuevo modo de operación del microprocesador. Aparte del modo real
(el normal de operación) que direcciona hasta 1 Mb de memoria física y asegura la
compatibilidad para aplicaciones diseñadas par los 8086/8088, se tiene el modo protegido
que no es compatible con estos programas desarrollados para los micros antes
mencionados. El modo protegido es el que permite acceder a los 1.008 Mb de memoria
virtual.

El 80286 trabaja en su arranque en modo real. El cambio a modo protegido, lo que se


conoce técnicamente como upshift, no es reversible (downshift), siendo necesario hacer
un reset del microprocesador para volver al modo real; sin duda un gran fallo de diseño.
El 80286 se presentó con velocidades de reloj de 2, 8, 10, 12, 16 y 20 MHz.

80386 DX y SX.

M. D. O. H. Sonia Alvarado Mares


12
Lenguaje Ensamblador

Introducido en 1985, el 80386 DX supera un nuevo escalón en el avance tecnológico en


microprocesadores. Se incorpora una nueva ampliación y surge el número mágico, el 32.

Los buses de datos y de direcciones se amplían hasta 32 líneas de datos, ocurriendo lo


mismo con el tamaño de los registros. Esta ampliación supone un incremento en la
memoria RAM física instalada. Puede direccionar 4 Gb de memoria física (DX significa
Double word eXternal) y 64 Tb de memoria virtual, una cifra que en la actualidad está aún
muy por encima de las posibilidades económicas de los usuarios (a ver quién instala
4.000 Megabytes de RAM, unos 20 millones de pesetas).

Arranca en modo real, al igual que el 80286, e incorpora un nuevo modo de operación: el
modo real virtual del 8086, que permite tener varias sesiones 8086 trabajando
simultáneamente simulando una especie de pseudomultitarea.

En los microprocesadores anteriores la gestión de memoria se realizaba en segmentos de


16 Kb. Con el 80286 este tamaño de los segmentos de la memoria se hacían muy
pequeños y el programador tenía que trabajar más para adaptarse a una gran cantidad de
segmentos. El 80386 permite la definición de segmentos de memoria de tamaño variable.
Aparte, Intel corrigió la deficiencia del downshifting, pudiéndose realizar por software.

Otra de las innovaciones en la inclusión de una memoria caché interna en el chip


destinada a almacenar instrucciones provenientes de memoria sin necesidad de que la
unidad de ejecución intervenga. Intel comete un nuevo error en el diseño del micro que
genera inexactitudes en el cálculo de 32 bits, que se presentan en los micros lanzados al
mercado hasta mayo del 1987. Los modelos corregidos van etiquetados con una doble
sigma mayúscula o con el identificativo DX. Este error afectaba a las operaciones de
multiplicación de 32 bits. Ocurría bajo las siguientes circunstancias:

• Se usa la memoria virtual y se produce una demanda de página.


• El coprocesador matemático 80387 está instalado y en uso.
• Debe ocurrir una operación de acceso directo a memoria (DMA).
• El 80386 debe estar en estado de espera (Wait State).

Se detecta un segundo bug denominado POPAD bug. Su efecto es el vaciado del registro
acumulador EAX cuando se ejecuta una instrucción de acceso a memoria inmediatamente
después de la ejecución de la instrucción POPAD.

Aparecen variaciones que afectan al consumo de energía pensadas para portátiles, se


trataba de los 80386SL (Slow Low power) y 80386SLC (Slow Low power Cache), que es
propiedad de IBM aunque lo fabrique Intel. Las frecuencias de funcionamiento eran de 12,
20, 25 y 33 MHz.

80386 SX .

(SX significa Simple word eXternal) tiene las mismas características que el 80386DX,
salvo que el bus de direcciones externo se reduce a 16 bits. Introducido en 1988 daba la
potencia de un 80386 a precio de un 80286. Durante mucho tiempo se rumoreó que el P9
podría ser compatible con los zócalos 80286, pero al final no fue así. La razón es que el
80286 multiplexa todos sus buses para conseguir con menos líneas el mismo resultado

M. D. O. H. Sonia Alvarado Mares


13
Lenguaje Ensamblador

(menor coste) El 80386SX sólo multiplexa el bus de direcciones. Las frecuencias de


funcionamiento eran de 16, 20, 25 y 33 MHz.

80486 DX, 80486 SX.

El 80486DX salió al mercado en 1989. La estructura interna hablando en términos


numéricos es igual a la de un 80386. El tamaño de los registros y de los buses son de 32
bits. Mantiene los tres modos de operación: real, protegido y real virtual. Las diferencias
reales con los 80386DX son que tiene un flag más, un estado de excepción más, 2 bits
más en la tabla de entrada de páginas, 6 instrucciones y los registros de control tienen
una longitud de 9 bits.

Se realizan también cambios en la arquitectura interna. Se crea un mayor número de


líneas hardware lo que implica un incremento en la velocidad. Se imponen reglas de
diseño más estrictas, lo que supone un reducción del tamaño del chip. Al reducirse el
tamaño se reduce también el consumo y consiguientemente la temperatura que alcanza el
chip, con lo cual lo podemos hacer funcionar a un mayor número de ciclos de reloj, lo que
supondrá la aparición de los Overdrives.

Se incluye un coprocesador matemático interno que dobla las prestaciones de un 80387


trabajando a la misma velocidad. Se logra un diseño mejor y la comunicación entre el chip
principal y el coprocesador matemático es interna, lo que mejora la velocidad en las
transferencias y unas sincronizaciones más estrechas.

La memoria cache (8 Kb) del microprocesador está dividida en 4 caches de 2 Kb cada


una. Esto agiliza la ejecución de algunas aplicaciones. Si se asigna una memoria cache
secundaria (L2) el rendimiento del micro puede aumentar hasta un 30 por ciento más.

El 80486SX es igual que un 80486DX, sólo que el coprocesador matemático está


inhabilitado. El coprocesador matemático 80487SX es en realidad un 80486DX puro que
desactiva por completo el 80486SX, sin que podamos retirarlo de la placa. Las
velocidades a las que funcionan son de 25, 33, 40 y 50 MHz. Hay versión SL para
portátiles.

80486 DX2, 80486 DX4, 80486 SX2.

Estos modelos de microprocesadores en realidad son iguales que sus hermanos


menores. Internamente duplican la velocidad del reloj del sistema. Es igual que
revolucionar el motor de un coche para que corra más. Las consecuencias son obvias: un
sobrecalentamiento del micro con una reducción de potencia. Por este motivo se
recomienda utilizar un método de disipación de calor para que el rendimiento no se vea
reducido (laminillas disipadoras o ventiladores). Las velocidades a las que trabajan son:
50, 66, 75 y 100 (sólo para el DX4) MHz para los DX2 y 40 y 50 MHz para los SX2.

Los 80486 tampoco están libres del pecado original. En el 80486 cuando el coprocesador
matemático detecta un error de límite del tamaño de segmento, algunas veces la CPU
falla al generar la excepción 13. Este error se genera bajo las siguientes condiciones:

• Segmento de datos de 64 Kb.


• Operandos de direccionamiento de 16 bits.

M. D. O. H. Sonia Alvarado Mares


14
Lenguaje Ensamblador

• Almacenar un valor de 8 bytes desde el coprocesador cuando la mitad está fuera


de los límites del límite del segmento.
• Un segundo bug aparece en el cálculo de la instrucción dedicada a calcular
arcotangentes.

Overdrives Intel comenzó una nueva política con la salida de los microprocesadores con
la denominación Overdrive. Los Overdrive eran actualizaciones para los
microprocesadores instalados en los sistemas que dispusieran de un segundo zócalo para
tal propósito. En esta primera generación de Overdrives los chips disponían de un
duplicador de frecuencia interno y tenían un pin más, el número 169. Este pin se
encargaba de inhabilitar el 80486 instalado en la placa dejando como único micro
funcionando el Overdrive. No era posible la retirada del micro anterior, puesto que el
sistema dejaba de funcionar. La política de actualización era buena, lo que no era tan
bueno era la trampa para los usuarios. Si se puede retirar el micro anterior se puede
vender a usuarios que necesiten menos potencia, no siendo tan gravosa la inversión de
más de 80.000 pesetas que costaban cuando salieron los primeros en 1991.

En la segunda generación de Overdrives se olvidó el pin 169, teniendo los 168 que los
hacían compatibles con los zócalos de los 80486. En estos casos la actualización es
sencillísima: quitar el que estaba y poner el nuevo en el mismo lugar.

La tercera generación de Overdrives trabaja con un consumo menor para reducir de este
modo su alta temperatura. El voltaje se reduce a 3.3 voltios de los 5 que necesitaban los
anteriores. Si vas a comprar un DX2 o DX4 fíjate bien qué voltaje utiliza vuestra placa. los
Overdrives etiquetados como tal funcionan a 5V, los etiquetados directamente como DX4,
sin disipador, funcionan a 3.3V.

Microprocesadores Modernos.

Pentium MMX.

Es un micro propio de la filosofía Intel. Con un gran chip como el Pentium Pro ya en el
mercado, y a 3 meses escasos de sacar el Pentium II, decidió estirar un poco más la
tecnología ya obsoleta del Pentium clásico en vez de ofrecer esas nuevas soluciones a un
precio razonable.

Así que se inventó un nuevo conjunto de instrucciones para micro, que para ser modernos
tuvieran que ver con el rendimiento de las aplicaciones multimedia, y las llamó MMX
(MultiMedia eXtensions). Prometían que el nuevo Pentium, con las MMX y el doble de
caché (32 KB), podía tener ¡hasta un 60% más de rendimiento!!

En ocasiones, la ventaja puede llegar al 25%, y sólo en aplicaciones muy optimizadas


para MMX (ni Windows 95 ni Office lo son, por ejemplo). En el resto, no más de un 10%,
que además se debe casi en exclusiva al aumento de la caché interna al doble.

¿La ventaja del chip, entonces? Que su precio final acaba siendo igual que si no fuera
MMX. Además, consume y se calienta menos por tener voltaje reducido para el núcleo del

M. D. O. H. Sonia Alvarado Mares


15
Lenguaje Ensamblador

chip (2,8 V). Por cierto, el modelo a 233 MHz (66 MHz en placa por 3,5) está tan
estrangulado por ese "cuello de botella" que rinde poco más que el 200 (66 por 3).

Pentium II.

¿El nuevo super-extra-chip? Pues no del todo. En realidad, se trata del viejo Pentium Pro,
jubilado antes de tiempo, con algunos cambios (no todos para mejor) y en una nueva y
fantástica presentación, el cartucho SEC: una cajita negra superchula que en vez de a un
zócalo se conecta a una ranura llamada Slot 1.

Los cambios respecto al Pro son:

• optimizado para MMX (no sirve de mucho, pero hay que estar en la onda, chicos);
• nuevo encapsulado y conector a la placa (para eliminar a la competencia, como
veremos);
• rendimiento de 16 bits mejorado (ahora sí es mejor que un Pentium en Windows 95,
pero a costa de desaprovecharlo; lo suyo son 32 bits puros);
• caché secundaria encapsulada junto al chip (semi-interna, como si dijéramos), pero
a la mitad de la velocidad de éste (un retroceso desde el Pro, que iba a la misma
velocidad; abarata los costes de fabricación).

Vamos, un chip "Pro 2.0", con muchas luces y algunas sombras. La mayor sombra, su
método de conexión, el "Slot 1"; Intel lo patentó, lo que es algo así como patentar un
enchufe cuadrado en vez de uno redondo. El caso es que la jugada buscaba conseguir
que los PC fueran todos marca Intel; ¡y decían que los sistemas propietarios eran cosa de
Apple!

Eso sí, durante bastante tiempo fue el mejor chip del mercado, especialmente desde que
se dejó de fabricar el Pro.

AMD K6.

Un chip meritorio, mucho mejor que el K5. Incluía la "magia" MMX, aparte de un diseño
interno increíblemente innovador y una caché interna de 64 KB (no hace demasiado, ese
tamaño lo tenían las cachés externas; casi da miedo).

Se "pincha" en un zócalo de Pentium normal (un socket 7, para ser precisos) y la caché
secundaria la tiene en la placa base, a la manera clásica. Pese a esto, su rendimiento es
muy bueno: mejor que un MMX y sólo algo peor que un II, siempre que se pruebe en
Windows 95 (NT es terreno abonado para el Pentium II).

Aunque es algo peor en cuanto a cálculos de coma flotante (CAD y juegos), para oficina
es la opción a elegir en todo el mundo... excepto España. Aquí nos ha encantado lo de
"Intel Pentium Inside", y la gente no compra nada sin esta frase, por lo que casi nadie lo
vende y mucho menos a los precios ridículos de lugares como EEUU o Alemania. Oferta y

M. D. O. H. Sonia Alvarado Mares


16
Lenguaje Ensamblador

demanda, como todo; no basta con una buena idea, hay que convencer. De todas formas,
hasta IBM lo usa en algunos de sus equipos; por algo será.

6x86MX (M2) de Cyrix (o IBM).

Nada que añadir a lo dicho sobre el 6x86 clásico y el K6 de AMD; pues eso, un chip muy
bueno para trabajo de oficinas, que incluye MMX y que nunca debe elegirse para CAD o
juegos (peor que los AMD).

Celeron (Pentium II light).

En breve: un Pentium II sin la caché secundaria. Pensado para liquidar el mercado de


placas base tipo Pentium no II (con socket 7, que se dice) y liquidar definitivamente a
AMD y otras empresas molestas que usan estas placas. Esta gente de Intel no tiene
compasión, sin duda...

Muy poco recomendable, rendimiento mucho más bajo que el de Pentium II, casi idéntico
al del Pentium MMX.

AMD K6-2 (K6-3D).

Consiste en una revisión del K6, con un núcleo similar pero añadiéndole capacidades 3D
en lo que AMD llama la tecnología 3DNow! (algo así como un MMX para 3D). Además,
generalmente trabaja con un bus de 100 MHz hacia caché y memoria, lo que le hace
rendir igual que un Pentium II en casi todas las condiciones e incluso mucho mejor que
éste cuando se trata de juegos 3D modernos (ya que necesitan estar optimizados para
este chip o bien usar las DirectX 6 de Microsoft).

Pentium III.

El Pentium III es un microprocesador de arquitectura i686 fabricado por Intel; el cual es


una modificación del Pentium Pro. Existen tres versiones de Pentium III: Katmai,
Coppermine y Tualatin.

Pentium 4.

El Pentium 4 (erróneamente escrito Pentium IV) es un microprocesador de séptima


generación basado en la arquitectura x86 y fabricado por Intel. Es el primer
microprocesador con un diseño completamente nuevo desde el Pentium Pro de 1995. El
Pentium 4 original, denominado Willamette, trabajaba a 1,4 y 1,5 GHz;

Pentium M.

El Pentium M representa un cambio radical para Intel, ya que no es una versión de bajo
consumo del Pentium 4, sino una versión fuertemente modificada del diseño del Pentium
III (que a su vez es una modificación del Pentium Pro).
M. D. O. H. Sonia Alvarado Mares
17
Lenguaje Ensamblador

Los miembros de la familia Pentium M son los siguientes:

• Pentium M Banias
• Pentium M Dothan
• Pentium M Dothan (SonomaPentium M Yonah (Core Solo y Core Duo)

Pentium D.

Los procesadores Pentium D fueron introducidos por Intel en el verano de 2005 Intel
Developer Forum. Un chip Pentium D consiste básicamente en dos procesadores Pentium
4 (de núcleo Prescott) en una única pieza de silicio con un proceso de fabricación de 90
nm. El nombre en clave del Pentium D antes de su lanzamiento era "Smithfield". Incluye
una tecnología DRM (Digital Rights Management) para hacer posible un sistema de
protección anticopia de la mano de Microsoft.

Existen Seis variantes del Pentium D:

• Pentium D 805, a 2.6 GHz


• Pentium D 820, a 2.8 GHz
• Pentium D 830, a 3.0 GHz
• Pentium D 840, a 3.2 GHz
• Pentium D Extreme Edition, a 3.2 GHz, con Hyper Threading.

Intel Core Duo.

Este microprocesador implementa 2Mb de caché compartida para ambos núcleos más un
bus frontal de 667Mhz; además implementa un nuevo juego de instrucciones para
multimedia (SSE3) y mejoras para las SSE y SSE2, sin embargo, el desempeño con
enteros es ligeramente inferior debido a su caché con mayor latencia.

Intel Core 2 Duo.

El procesador Core 2 Duo de Intel es la continuación de los Pentium D y Core Duo. El


acceso a memoria inteligente optimiza el ancho de banda de datos. Su arquitectura se
basa en la del Pentium M, pues demostró ser mucho más eficiente que la arquitectura de
Pentium 4.

Intel Core 2 Quad.

Core 2 Quad o Core Quad son la nueva serie de procesadores de Intel de 4 núcleos (no
confundir con Core 2 Extreme) que salió al mercado en el primer trimestre del 2007. Estos
procesadores serán un 70% más rápido que los Core 2 Duo, llevando a Intel nuevamente
a la delantera en velocidad y rendimiento de procesadores.

M. D. O. H. Sonia Alvarado Mares


18
Lenguaje Ensamblador

Desarrollo de los Microprocesadores Intel.

Ancho
Fecha de Velocidad Número de Memoria Memoria Breve
Procesador de
presentación de reloj transistores direccionable virtual descripción
bus
Primer chip
2.300 (10 con
4004 15/11/71 108 KHz. 4 bits 640 byte
micras) manipulación
aritmética

Manipulación
8008 1/4/72 108 KHz. 8 bits 3.500 16 KBytes
Datos/texto

10 veces las
(6 micras)
8080 1/4/74 2 MHz. 8 bits 6.000 64 KBytes
prestaciones
del 8008

5 MHz. 10 veces las


29.000
8086 8/6/78 8 MHz. 16 bits 1 MegaByte prestaciones
(3 micras) del 8080
10 MHz.

Idéntico al
5 MHz. 8086 excepto
8088 1/6/79 8 bits 29.000 en su bus
8 MHz. externo de 8
bits

8 MHz. De 3 a 6
134.000 1 veces las
80286 1/2/82 10 MHz. 16 Bits 16 Megabytes
(1.5 micras) Gigabyte prestaciones
12 MHz. del 8086

Primer chip
16 MHz. x86 capaz de
Microprocesador 20 MHz. 275.000 64 manejar
17/10/85 32 Bits 4 Gigabytes
Intel 386 DX® 25 MHz. (1 micra) Terabytes juegos de
33 MHz. datos de 32
bits

Bus capaz de
direccionar 16
Microprocesador 16 MHz. 275.000 64 bits
16/6/88 16 Bits 4 gigabytes
Intel 386 SX® 20 MHz. (1 micra) Terabytes procesando
32bits a bajo
coste

M. D. O. H. Sonia Alvarado Mares


19
Lenguaje Ensamblador

Tabla 1.1 Desarrollo de los microprocesadores de Intel.

Desarrollo de los Microprocesadores Intel.


(continación)

Ancho
Fecha de Velocidad Número de Memoria Memoria Breve
Procesador de bus
presentación de reloj transistores direccionable virtual descripción

Bus capaz de
direccionar 16
Microprocesador 16 MHz. 275.000 64 bits
16/6/88 16 Bits 4 gigabytes
Intel 386 SX® 20 MHz. (1 micra) Terabytes procesando
32bits a bajo
coste

25 MHz. (1 micra, 0.8 Caché de


Microprocesador 64
10/4/89 33 MHz. 32 Bits micras en 50 4 Gigabytes nivel 1 en el
Intel 486 DX® MHz.) Terabytes chip
50 MHz.

Idéntico en
16 MHz. diseño al Intel
Microprocesador 20 MHz. 1.185.000 64 486DX, pero
22/4/91 32 Bits 4 Gigabytes
Intel 486 SX® 25 MHz. (0.8 micras) Terabytes sin
33 MHz. coprocesador
matemático

60 MHz.
66 MHz.
75 MHz. Arquitectura
90 MHz. escalable.
Procesador 100 MHz. 3,1 millones 64 Hasta 5
22/3/93 32 Bits 4 Gigabytes veces las
Pentium® 120 MHz. (0.8 micras) Terabytes prestaciones
133 MHz. del 486 DX a
150 MHz. 33 MHz.
166 MHz.
200 MHz.

Arquitectura
150 MHz. de ejecución
Procesador 5,5 millones 64 dinámica con
27/3/95 180 MHz. 64 Bits 4 Gigabytes
PentiumPro® (0.32 micras) Terabytes procesador
200 MHz. de altas
prestaciones

Procesador 7/5/97 233 MHz. 64 Bits 7,5 millones 4 Gigabytes 64 S.E.C., MMX,
PentiumII® 266 MHz. (0.32 micras) Terabytes Doble Bus
Indep.,
300 MHz.

M. D. O. H. Sonia Alvarado Mares


20
Lenguaje Ensamblador

Ejecución
Dinámica

Tabla 1.1 Desarrollo de los microprocesadores de Intel (continuación).

1.1.3 Tipos de lenguajes ensambladores.

Aunque todos los ensambladores realizan básicamente las mismas tareas, podemos
clasificarlos de acuerdo a características. Así podemos clasificarlos en:

Ensambladores Cruzados (Cross-Assembler).

Se denominan así los ensambladores que se utilizan en una computadora que posee un
procesador diferente al que tendrán las computadoras donde va a ejecutarse el programa
objeto producido.

El empleo de este tipo de traductores permite aprovechar el soporte de medios físicos


(discos, impresoras, pantallas, etc.), y de programación que ofrecen las máquinas
potentes para desarrollar programas que luego los van a ejecutar sistemas muy
especializados en determinados tipos de tareas.

Ensambladores Residentes.

Son aquellos que permanecen en la memoria principal de la computadora y cargan, para


su ejecución, al programa objeto producido. Este tipo de ensamblador tiene la ventaja de
que se puede comprobar inmediatamente el programa sin necesidad de transportarlo de
un lugar a otro, como se hacía en cross-assembler, y sin necesidad de programas
simuladores.

Sin embargo, puede presentar problemas de espacio de memoria, ya que el traductor


ocupa espacio que no puede ser utilizado por el programador. Asimismo, también ocupará
memoria el programa fuente y el programa objeto. Esto obliga a tener un espacio de
memoria relativamente amplio. Es el indicado para desarrollos de pequeños sistemas de
control y sencillos automatismo empleando microprocesadores.

La ventaja de estos ensambladores es que permiten ejecutar inmediatamente el


programa; la desventaja es que deben mantenerse en la memoria principal tanto el
ensamblador como el programa fuente y el programa objeto.

Macroensambladores.

Son ensambladores que permiten el uso de macroinstrucciones (macros). Debido a su


potencia, normalmente son programas robustos que no permanecen en memoria una vez
generado el programa objeto. Puede variar la complejidad de los mismos, dependiendo de

M. D. O. H. Sonia Alvarado Mares


21
Lenguaje Ensamblador

las posibilidades de definición y manipulación de las macroinstrucciones, pero


normalmente son programas bastantes complejos, por lo que suelen ser ensambladores
residentes.

Microensambladores.

Generalmente, los procesadores utilizados en las computadoras tienen un repertorio fijo


de instrucciones, es decir, que el intérprete de las mismas interpretaba de igual forma un
determinado código de operación.

El programa que indica al intérprete de instrucciones de la UCP cómo debe actuar se


denomina microprograma. El programa que ayuda a realizar éste microprograma se llama
microensamblador. Existen procesadores que permiten la modificación de sus
microprogramas, para lo cual se utilizan microensambladores.

Ensambladores de una fase.

Estos ensambladores leen una línea del programa fuente y la traducen directamente para
producir una instrucción en lenguaje máquina o la ejecuta si se trata de una
pseudoinstrucción. También va construyendo la tabla de símbolos a medida que van
apareciendo las definiciones de variables, etiquetas, etc.

Debido a su forma de traducción, estos ensambladores obligan a definir los símbolos


antes de ser empleados para que, cuando aparezca una referencia a un determinado
símbolo en una instrucción, se conozca la dirección de dicho símbolo y se pueda traducir
de forma correcta. Estos ensambladores son sencillos, baratos y ocupan poco espacio,
pero tiene el inconveniente indicado.

Ensambladores de dos fases.

Los ensambladores de dos fases se denominan así debido a que realizan la traducción en
dos etapas. En la primera fase, leen el programa fuente y construyen una tabla de
símbolos; de esta manera, en la segunda fase, vuelven a leer el programa fuente y
pueden ir traduciendo totalmente, puesto que conocen la totalidad de los símbolos
utilizados y las posiciones que se les ha asignado. Estos ensambladores son los más
utilizados en la actualidad.

M. D. O. H. Sonia Alvarado Mares


22
Lenguaje Ensamblador

1.1.4 Clasificación de memorias.

Las memorias han evolucionado mucho desde los comienzos del mundo de la
computación. Conviene recordar los tipos de memorias de semiconductores empleadas
como memoria principal y unas ligeras pinceladas sobre cada una de ellas para enmarcar
las memorias flash dentro de su contexto.

Jerarquía de memoria.

En un ordenador hay una jerarquía de memorias atendiendo al tiempo de acceso y a la


capacidad que normalmente son factores contrapuestos por razones económicas y en
muchos casos también físicas. Comenzando desde el procesador al exterior, es decir en
orden creciente de tiempo de acceso y capacidad, se puede establecer la siguiente
jerarquía:

Registros de procesador. Estos registros interaccionan continuamente con la CPU


(porque forman parte de ella). Los registros tienen un tiempo de acceso muy pequeño y
una capacidad mínima, normalmente igual a la palabra del procesador (1 a 8 bytes).

Registros intermedios. Constituyen un paso intermedio entre el procesador y la


memoria, tienen un tiempo de acceso muy breve y muy poca capacidad.

Memorias caché. Son memorias de pequeña capacidad. Normalmente una pequeña


fracción de la memoria principal y pequeño tiempo de acceso. Este nivel de memoria se
coloca entre la CPU y la memoria central. Hace algunos años este nivel era exclusivo de
los ordenadores grandes pero actualmente todos los ordenadores lo incorporan. Dentro
de la memoria caché puede haber, a su vez, dos niveles denominados caché on chip,
memoria caché dentro del circuito integrado, y caché on board, memoria caché en la
placa de circuito impreso pero fuera del circuito integrado, evidentemente, por razones
físicas, la primera es mucho más rápida que la segunda. Existe también una técnica,
denominada Arquitectura Harvard, en cierto modo contrapuesta a la idea de Von
Newmann, que utiliza memorias caché separadas para código y datos. Esto tiene algunas
ventajas.

Memoria central o principal. En este nivel residen los programas y los datos. La CPU
lee y escribe datos en él aunque con menos frecuencia que en los niveles anteriores.
Tiene un tiempo de acceso relativamente rápido y gran capacidad.

Extensiones de memoria central. Son memorias de la misma naturaleza que la memoria


central que amplían su capacidad de forma modular. El tiempo de similar, a lo sumo un
poco mayor, al de la memoria central y su capacidad puede ser algunas veces mayor.

Memorias de masas o auxiliares. Son memorias que residen en dispositivos externos al


ordenador, en ellas se archivan programas y datos para su uso posterior. También se
M. D. O. H. Sonia Alvarado Mares
23
Lenguaje Ensamblador

usan estas memorias para apoyo de la memoria central en caso de que ésta sea
insuficiente (memoria virtual). Estas memorias suelen tener gran capacidad pero pueden
llegar a tener un tiempo de acceso muy lento. Dentro de ellas también se pueden
establecer varios niveles de jerarquía.

Categorías de memorias.

Las memorias se clasifican, por la tecnología empleada y, además según la forma en que
se puede modificar su contenido.

Organizando estos tipos de memoria conviene destacar tres categorías si las clasificamos
en función de las operaciones que podemos realizar sobre ellas, es decir, memorias de
sólo lectura, memorias de sobre todo lectura y memorias de lectura escritura.

Memorias de sólo lectura.

ROM: Se usan principalmente en microprogramación de sistemas. Los fabricantes las


suelen emplear cuando producen componentes de forma masiva.

Es una memoria solamente de lectura es totalmente inalterable sin esta memoria la


máquina no arrancaría. La memoria principal es la convencional que va de 0 a 640 kb.
Cuando la máquina arranca comienza a trabajar el disco y realiza un testeo, para lo cual
necesita memoria, esta memoria es la convencional (ROM) y está dentro de la tarjeta
madre (en el BIOS). Apenas arranca utiliza 300 kb, sigue testeando y llega a más o
menos 540 kb donde se planta. A medida de que comenzó a haber software con más
necesidad de memoria apareció la llamada memoria expandida que iba de 640 kb a 1024
kb. Una vez que se utilizaba toda la memoria convencional se utilizaba la expandida que
utiliza la memoria RAM. A medida que pasa el tiempo los 1024 kb eran escasos y se creo
la memoria extendida que va de 1024 kb a infinito que es la memoria RAM pura.

PROM: (Programmable Read Only Memory): El proceso de escritura es eléctrico. Se


puede grabar posteriormente a la fabricación del chip, a diferencia de las anteriores que
se graba durante la fabricación. Permite una única grabación y es más cara que la ROM.

Es una memoria digital donde el valor de cada bit depende del estado de un fusible (o
antifusible), que puede ser quemado una sola vez. Por esto la memoria puede ser
programada (pueden ser escritos los datos) una sola vez a través de un dispositivo
especial, un programador PROM. Estas memorias son utilizadas para grabar datos
permanentes en cantidades menores a las ROM´s, o cuando los datos deben cambiar en
muchos o todos los casos.

Pequeñas PROM han venido utilizándose como generadores de funciones, normalmente


en conjunción con un multiplexor. A veces se preferían a las ROM porque son bipolares,
consiguiendo mayores velocidades. Una PROM común se encuentra con todos los bits en
valor 1 como valor por defecto de fábrica; el quemado de cada fusible, cambia el valor del
correspondiente bit a 0. La programación se realiza aplicando pulsos de altos voltajes que
no se encuentran durante operaciones normales (12 a 21 voltios). El término Read-only

M. D. O. H. Sonia Alvarado Mares


24
Lenguaje Ensamblador

(sólo lectura) se refiere a que, a diferencia de otras memorias, los datos no pueden ser
cambiados (al menos por el usuario final).

Memorias de sobre todo lectura.


lectura.

EPROM: (EPROM son las siglas de Erasable Programmable Read-Only Memory; ROM
borrable programable). Es un tipo de chip de memoria ROM inventado por el ingeniero
Dov Frohman que retiene los datos cuando la fuente de energía se apaga. En otras
palabras, es no volátil.

Está formada por celdas de FAMOS (Floating Gate Avalanche-Injection Metal-Oxide


Semiconductor) o transistores de puerta flotante. Cada uno de ellos viene de fábrica sin
carga, por lo que es leído como un 1 (por eso una EPROM sin grabar se lee como FF en
todas sus celdas). Se programan mediante un dispositivo electrónico que proporciona
voltajes superiores a los normalmente utilizados en los circuitos electrónicos. Las celdas
que reciben carga se leen entonces como un 0. Una vez programada, una EPROM se
puede borrar solamente mediante exposición a una fuerte luz ultravioleta. Esto es debido
a que los fotones de la luz excitan a los electrones de las celdas provocando que se
descarguen. Las EPROM’s se reconocen fácilmente por una ventana transparente en la
parte alta del encapsulado, a través de la cual se puede ver el chip de silicio y que admite
la luz ultravioleta durante el borrado.

EEPROM: son las siglas de Electrically-Erasable Programmable Read-Only Memory


(ROM programable y borrable eléctricamente), o en español o castellano se suele referir
al hablar como EEPROM y en inglés “E-Squared-PROM”. Es un tipo de memoria ROM
que puede ser programado, borrado y reprogramado eléctricamente, a diferencia de la
EPROM que ha de borrarse mediante rayos ultravioletas. Esta memoria también es
conocida como EAROM (electrically alterable ROM).

Aunque una EEPROM puede ser leída un número ilimitado de veces, sólo puede ser
borrada y reprogramada entre 100.000 y 1.000.000 de veces. Estos dispositivos suelen
comunicarse mediante protocolos como IC, SPI y Microwire. En otras ocasiones se
integra dentro de chips como microcontroladores y DSPs para lograr una mayor rapidez.
La memoria flash es una forma avanzada de EEPROM creadas por Dr. Fujio Masuoka
mientras trabajaba para Toshiba in 1984 y fueron presentadas en la Reunón de Aparatos
Electrónicos de la IEEE de 1984. Intel vió el potencial de la invención y en 1988 lanzó el
primer chip comercial del tipo NOR.

Memoria Flash: Está basada en las memorias EEPROM pero permite el borrado bloque
a bloque y es más barata y densa.

La memoria flash es una forma evolucionada de la memoria EEPROM que permite que
múltiples posiciones de memoria sean escritas o borradas en una misma operación de
programación mediante impulsos eléctricos, frente a las anteriores que sólo permite
escribir o borrar una única celda cada vez. Por ello, flash permite funcionar a velocidades
muy superiores cuando los sistemas emplean lectura y escritura en diferentes puntos de
esta memoria al mismo tiempo. Flash, como tipo de EEPROM que es, contiene un arreglo
M. D. O. H. Sonia Alvarado Mares
25
Lenguaje Ensamblador

de celdas con un transistor evolucionado con dos puertas en cada intersección.


Tradicionalmente sólo almacenan un bit de información. Las nuevas memorias flash,
llamadas también dispositivos de celdas multi-nivel, pueden almacenar más de un bit por
celda variando el número de electrones que almacenan.

Estas memorias están basada en el transistor FAMOS (Floating Gate Avalanche-Injection


Metal Oxide Semiconductor) que es, esencialmente un transistor NMOS con un conductor
(basado en un óxido metálico) adicional entre la puerta de control (CG – Control Gate) y
los terminales fuente/drenador contenidos en otra puerta (FG – Floating Gate) o bien que
rodea a FG y es quien contiene los electrones que almacenan la información.

Memoria flash de tipo NOR: Cuando los electrones se encuentran en FG, modifican
(prácticamente anulan) el campo eléctrico que generaría CG en caso de estar activo.

De esta forma, dependiendo de si la celda está a 1 ó a 0, el campo eléctrico de la celda


existe o no. Entonces, cuando se lee la celda poniendo un determinado voltaje en CG, la
corriente eléctrica fluye o no en función del voltaje almacenado en la celda. La
presencia/ausencia de corriente se detecta e interpreta como un 1 ó un 0, reproduciendo
así el dato almacenado. En los dispositivos de celda multi-nivel, se detecta la intensidad
de la corriente para controlar el número de electrones almacenados en FG e interpretarlos
adecuadamente.

Para programar una celda de tipo NOR (asignar un valor determinado) se permite el paso
de la corriente desde el terminal fuente al terminal sumidero, entonces se coloca en CG
un voltaje alto para absorber los electrones y retenerlos en el campo eléctrico que genera.

Este proceso se llama hot-electron injection. Para borrar (poner a “1”, el estado natural del
transistor) el contenido de una celda, expulsar estos electrones, se emplea la técnica de
Fowler-Nordheim tunnelling, un proceso de tunelado mecánico – cuántico. Esto es, aplicar
un voltaje inverso bastante alto al empleado para atraer a los electrones, convirtiendo al
transistor en una pistola de electrones que permite, abriendo el terminal sumidero, que los
electrones abandonen el mismo. Este proceso es el que provoca el deterioro de las
celdas, al aplicar sobre un conductor tan delgado un voltaje tan alto.

Cabe destacar que las memorias flash están subdividas en bloques (en ocasiones
llamados sectores) y por lo tanto, para el borrado, se limpian bloques enteros para agilizar
el proceso, ya que es la parte más lenta del proceso. Por esta razón, las memorias flash
son mucho más rápidas que las EEPROM convencionales, ya que borran byte a byte. No
obstante, para reescribir un dato es necesario limpiar el bloque primero para reescribir su
contenido después.

Memorias flash de tipo NAND: Basadas en puertas lógicas NAND funcionan de forma
ligeramente diferente: usan un túnel de inyección para la escritura y para el borrado un
túnel de ‘soltado’.

Las memorias basadas en NAND tienen, además de la evidente base en otro tipo de
puertas, un costo bastante inferior, unas diez veces de más resistencia a las operaciones
pero sólo permiten acceso secuencial (más orientado a dispositivos de almacenamiento
masivo), frente a las memorias flash basadas en NOR que permiten lectura de acceso

M. D. O. H. Sonia Alvarado Mares


26
Lenguaje Ensamblador

aleatorio. Sin embargo, han sido las NAND las que han permitido la expansión de este
tipo de memoria, ya que el mecanismo de borrado es más sencillo (aunque también se
borre por bloques) lo que ha proporcionado una base más rentable para la creación de
dispositivos de tipo tarjeta de memoria.

Comparación de memorias flash basadas en NOR y NAND. Para comparar estos tipos
de memoria se consideran los diferentes aspectos de las memorias tradicionalmente
valorados. La densidad de almacenamiento de los chips es actualmente bastante mayor
en las memorias NAND. El costo de NOR es mucho mayor. El acceso NOR es aleatorio
para lectura y orientado a bloques para su modificación. Sin embargo, NAND ofrece tan
solo acceso directo para los bloques y lectura secuencial dentro de los mismos. En la
escritura de NOR podemos llegar a modificar un solo bit. Esto destaca con la limitada
reprogramación de las NAND que deben modificar bloques o palabras completas. La
velocidad de lectura es muy superior en NOR (50–100 ns) frente a NAND (10 µs de la
búsqueda de la página + 50 ns por byte). La velocidad de escritura para NOR es de 5 µs
por byte frente a 200 µs por página en NAND. La velocidad de borrado para NOR es de
1 ms por bloque de 64 KB frente a los 2 ms por bloque de 16 KB en NAND. La fiabilidad
de los dispositivos basados en NOR es realmente muy alta, es relativamente inmune a la
corrupción de datos y tampoco tiene bloques erróneos frente a la escasa fiabilidad de los
sistemas NAND que requieren corrección de datos y existe la posibilidad de que queden
bloques marcados como erróneos e inservibles. En resumen, los sistemas basados en
NAND son más baratos y rápidos pero carecen de una fiabilidad que los haga eficiente, lo
que demuestra la necesidad imperiosa de un buen sistema de archivos. Dependiendo de
qué sea lo que se busque, merecerá la pena decantarse por uno u otro tipo.

Memorias de Lectura/Escritura (RAM).

Memoria RAM o Memoria e acceso Aleatorio (Random Acces Memory). Esta memoria
es como un escritorio al igual que los escritorios tienen cajones donde ordenan la
información, cuanto mas grande sea el escritorio (plano de apoyo) mas cajones voy a
tener de tal suerte que el micro va a perder menos tiempo en buscar y ordenar la
información.

La importancia de esta memoria es tan grande que si esta ausente la PC no arranca,


actúa como si estuviera muerta no hay sonido ni cursor en la pantalla ni luces que se
enciendan o apaguen. Para que sirve: Almacena las instrucciones que debe ejecutar el
micro en cada momento. Este es el lugar físico donde debe trabajar el procesador cuando
abrimos un programa sus instrucciones se copian automáticamente en la memoria, y
cuando cerremos el programa todo se borrara (volatizara). También copia los trabajos que
estamos haciendo en ese programa. En la RAM se copian programas que coordinan el
funcionamiento de la PC: La primera parte de la RAM esta reservada para guardar las
instrucciones de los dispositivos electrónicos. En este lugar no se puede guardar nada ya
que lo utiliza el sistema para saber como manejar los dispositivos.

DRAM (Dynamic Random Access Memory): Los datos se almacenan como en la carga
de un condensador. Tiende a descargarse y, por lo tanto, es necesario un proceso de
refresco periódico. Son más simples y baratas que las SRAM.

M. D. O. H. Sonia Alvarado Mares


27
Lenguaje Ensamblador

Este tipo de memorias se utilizan desde los años 80 hasta ahora en todas las
computadoras. Esta memoria tiene una desventaja hay que estimularla (Refresco)
permanentemente porque se olvida de todo. Como se estimula: requiere un procesador
que ordene el envió de cargas eléctricas, a este tipo de memorias se lo conoce como
memoria estáticas. Otras de las desventajas de esta memoria es que es lenta y la ventaja
es que es barata. Obviamente al tener estas desventajas se le incorporaron distintas
tecnologías para mejorarlas.

FPM DRAM. La ventaja de este memoria consiste en pedir permiso una sola vez u
llevarse varios datos consecutivos esto comenzó a usarse principios de los años noventa
y dió buenos resultados, a estos módulos se los denominaron SIMM, FPM, DRAM y
pueden tener 30 o 72 pines y se la utiliza en las Pentium I, lo que se logro con esta
tecnología es agilizar el proceso de lectura, estas memorias ya no se utilizan mas.

EDO DRAM. Estas memorias aparecieron en el 95, y se hicieron muy populares ya que
estaban presentes en todas las Pentium I MMX y tenían la posibilidad de localizar un dato
mientras transfería otro de diferencia de las anteriores que mientras transfería un dato se
bloqueaba. Estas EDO SIMM eran de 72 pines

RDRAM. Es una memoria muy costosa y de compleja fabricación y la utilizan procesador


Pentim IV para arriba, corre a velocidades de 800 Mhz, sus módulos se denominan RIMM
de 141 pines y con un ancho de 16 bits, para llenar un banco de memoria de 64 bits hay
que instalar 4 memorias, es posible que estas memoria sean retiradas del mercado por
ser tan costosas.

SDRAM. Esta Memoria entro en el mercado en los años 97, y mejoro la velocidad siendo
su ritmo de trabajo igual a la velocidad de Bus (FSB) es decir que tienen la capacidad de
trabajar a la misma velocidad de la tarjeta madre a la que se conectan.

Es tos módulos de 168 Pines son conocidos como DIMM SDRAM PC 66 y 100, 133,
obviamente si instalo una de 133, en una tarjeta madre de 100 va a funcionar a 100Mhz.

DDR SDRAM. En este caso se consiguió que pudiera realizar dos transferencia en una
pulsación o tic-tac de reloj, esta memoria pude alcanzar velocidades de 200 a 266Mhz,
Tiene una ventaja mas trabaja en sincronía con el bus de la tarjeta madre, si este acelera
la memoria también pero tiene una desventaja son muy caras. Se conoce como DIMM
DDR SDRAM PC 1600 Y PC 2100.

SRAM (Static Random Access Memory). Los datos se almacenan formando biestables,
por lo que no requiere refresco. Igual que DRAM es volátil. Son más rápidas que las
DRAM y más caras.

Memoria Caché o SRAM. La memoria caché trabaja igual que la memoria virtual,
tenemos caché en el procesador, en los discos y en el la tarjeta madre y nos guarda
direcciones de memoria.

Si ejecutamos un programa en principio, lo cerramos y luego los volvemos a ejecutar, la


memoria caché nos guarda la ubicación (dirección) en el disco, cuando lo ejecuté, y lo que
hicimos con el programa. Es mucho más rápida cuando ya usamos un programa.

Existen 3 tipos de memoria caché:

M. D. O. H. Sonia Alvarado Mares


28
Lenguaje Ensamblador

• Caché L1:
L1 Esta dividido en dos bloques uno contiene las instrucciones y otro los
datos y cuando se habla de su capacidad de almacenamiento se dice que es de
2×16 Kb. El caché L1 se encuentra dentro del interior del procesador y funciona a
la misma velocidad que el micro con capacidades que van desde 2×8 hasta
2×64Kb.

• Caché L2 interno y externo:


externo La primeras memoria caché estaban ubicadas en la
tarjeta madre luego se construyeron en el procesador, pero no dentro del dado del
procesador por lo que es mas lento que el caché L1, mientras que el externo lo
encontramos en la tarjeta madre. La computadoras que tienen las tres tecnologías
de caché van a ser mas rápidas.

• Cache L3:
L3 Algunos micro soportan un nivel de caché mas el L3 que esta localizado
en la tarjeta madre. EL AMD 6k-3 soporta este caché.

M. D. O. H. Sonia Alvarado Mares


29
Lenguaje Ensamblador

1.1.5 Unidades de Entrada / Salida.

Funciones que realiza.


realiza.

Vamos a señalar las funciones que debe realizar un computador para ejecutar trabajos de
entrada/salida:

• Direccionamiento o selección del dispositivo, que debe llevar a cabo la operación


de E/S.

• Transferencia de los datos entre el procesador y el dispositivo (en uno u otro


sentido).

• Sincronización y coordinación de las operaciones. Esta última función es necesaria


debido a la diferencia de velocidades entre los dispositivos y la CPU y a la
independencia que debe existir entre los periféricos y la CPU (por ejemplo, suelen
tener relojes diferentes).

Se define una transferencia elemental de información como la transmisión de una sola


unidad de información (normalmente un byte) entre el procesador y el periférico o
viceversa. Para efectuar una transferencia elemental de información son precisas las
siguientes funciones:

• Establecimiento de una comunicación física entre el procesador y el periférico para


la transmisión de la unidad de información.

• Control de los periféricos, en que se incluyen operaciones como prueba y


modificación del estado del periférico. Para realizar estas funciones la CPU
gestionará las líneas de control necesarias.

Definiremos una operación de E/S como el conjunto de acciones necesarias para la


transferencia de un conjunto de datos (es decir, una transferencia completa de datos).

Para la realización de una operación de E/S se deben efectuar las siguientes funciones:

• Recuento de las unidades de información transferidas (normalmente bytes) para


reconocer el fin de operación.

• Sincronización de velocidad entre la CPU y el periférico.

• Detección de errores (e incluso corrección) mediante la utilización de los códigos


necesarios (bits de paridad, códigos de redundancia cíclica, etc.)

M. D. O. H. Sonia Alvarado Mares


30
Lenguaje Ensamblador

• Almacenamiento temporal de la información. Es más eficiente utilizar un buffer


temporal específico para las operaciones de E/S que utilizan el área de datos del
programa.

• Conversión de códigos, conversión serie/paralelo, etc.

Dispositivos externos.

Una de las funciones básicas del ordenador es comunicarse con los dispositivos
exteriores, es decir, el ordenador debe ser capaz de enviar y recibir datos desde estos
dispositivos. Sin esta función, el ordenador no sería operativo porque sus cálculos no
serían visibles desde el exterior.

Existe una gran variedad de dispositivos que pueden comunicarse con un ordenador,
desde los dispositivos clásicos (terminales, impresoras, discos, cintas, etc.) hasta
convertidores A/D y D/A para aplicaciones de medida y control de procesos. De todos los
posibles periféricos, algunos son de lectura, otros de escritura y otros de lectura y
escritura (es importante resaltar que este hecho siempre se mira desde el punto de vista
del proceso). Por otra parte, existen periféricos de almacenamiento también llamados
memorias auxiliares o masivas.

La mayoría de los periféricos están compuestos por una parte mecánica y otra parte
electrónica. Estas partes suelen separarse claramente para dar una mayor modularidad. A
la componente electrónica del periférico se le suele denominar controlador del dispositivo
o, también, adaptador del dispositivo. Si el dispositivo no tiene parte mecánica (como, por
ejemplo, la pantalla de un terminal), el controlador estará formado por la parte digital del
circuito. Frecuentemente los controladores de los dispositivos están alojados en una placa
de circuito impreso diferenciada del resto del periférico. En este caso es bastante habitual
que un mismo controlador pueda dar servicio a dispositivos de características similares.

El principal problema planteado por los periféricos es su gran variedad que también afecta
a las velocidades de transmisión. Por tanto, el mayor inconveniente que encontramos en
los periféricos es la diferencia entre sus velocidades de transmisión y la diferencia entre
éstas y la velocidad de operación del ordenador.

Dispositivos de entrada.
entrada.

Estos dispositivos permiten al usuario del ordenador introducir datos, comandos y


programas en la CPU. El dispositivo de entrada más común es un teclado similar al de las
máquinas de escribir. La información introducida con el mismo, es transformada por el
ordenador en modelos reconocibles.

Otros dispositivos de entrada son los lápices ópticos, que transmiten información gráfica
desde tabletas electrónicas hasta el ordenador; joysticks y el ratón, que convierte el
movimiento físico en movimiento dentro de una pantalla de ordenador; los escáneres
luminosos, que leen palabras o símbolos de una página impresa y los traducen a
configuraciones electrónicas que el ordenador puede manipular y almacenar; y los

M. D. O. H. Sonia Alvarado Mares


31
Lenguaje Ensamblador

módulos de reconocimiento de voz, que convierten la palabra hablada en señales digitales


comprensibles para el ordenador.

También es posible utilizar los dispositivos de almacenamiento para introducir datos en la


unidad de proceso. Otros dispositivos de entrada, usados en la industria, son los
sensores.

Dispositivos de Entrada/Salida.
Entrada/Salida.

Los dispositivos de almacenamiento externos, que pueden residir físicamente dentro de la


unidad de proceso principal del ordenador, están fuera de la placa de circuitos principal.
Estos dispositivos almacenan los datos en forma de cargas sobre un medio
magnéticamente sensible, por ejemplo una cinta de sonido o, lo que es más común, sobre
un disco revestido de una fina capa de partículas metálicas.

Los dispositivos de almacenamiento externo más frecuentes son los disquetes y los
discos duros, aunque la mayoría de los grandes sistemas informáticos utiliza bancos de
unidades de almacenamiento en cinta magnética. Los discos flexibles pueden contener,
según sea el sistema, desde varios centenares de miles de bytes hasta bastante más de
un millón de bytes de datos. Los discos duros no pueden extraerse de los receptáculos de
la unidad de disco, que contienen los dispositivos electrónicos para leer y escribir datos
sobre la superficie magnética de los discos y pueden almacenar desde varios millones de
bytes hasta algunos centenares de millones. La tecnología de CD-ROM, que emplea las
mismas técnicas láser utilizadas para crear los discos compactos (CD) de audio, permiten
capacidades de almacenamiento del orden de varios cientos de megabytes (millones de
bytes) de datos. También hay que añadir los recientemente aparecidos DVD que permiten
almacenar más de 4 Gb de información.

Dispositivos de salida.
salida.

Estos dispositivos permiten al usuario ver los resultados de los cálculos o de las
manipulaciones de datos de la computadora.

El dispositivo de salida más común es la unidad de visualización, que consiste en un


monitor que presenta los caracteres y gráficos en una pantalla similar a la del televisor.
Por lo general, los monitores tienen un tubo de rayos catódicos como el de cualquier
televisor, aunque los ordena-dores pequeños y portátiles utilizan hoy pantallas de cristal
líquido (LCD, acrónimo de Liquid Crystal Displays) o electroluminiscentes. Otros
dispositivos de salida más comunes son las impresoras, que permiten obtener una copia
impresa de la información que reside en los dispositivos de almacenamiento, las tarjetas
de sonido y los módem.

M. D. O. H. Sonia Alvarado Mares


32
Lenguaje Ensamblador

Un módem enlaza dos ordenadores transformando las señales digitales en analógicas


para que los datos puedan transmitirse a través de las líneas telefónicas convencionales.

1.2 EL MICROPROCESADOR.

1.2.1 Buses.

Funciones que realiza el bus del sistema.

El bus se puede definir como un conjunto de líneas conductoras de hardware utilizadas


para la transmisión de datos entre los componentes de un sistema informático. Un bus es
en esencia una ruta compartida que conecta diferentes partes del sistema, como el
microprocesador, la controladora de unidad de disco, la memoria y los puertos de
entrada/salida (E/S), para permitir la transmisión de información.

En el bus se encuentran dos pistas separadas, el bus de datos y el bus de direcciones. La


CPU escribe la dirección de la posición deseada de la memoria en el bus de direcciones
accediendo a la memoria, teniendo cada una de las líneas carácter binario. Es decir solo
pueden representar 0 ó 1 y de esta manera forman conjuntamente el número de la
posición dentro de la memoria (es decir: la dirección). Cuantas más líneas hallan
disponibles, mayor es la dirección máxima y mayor es la memoria a la cual puede dirigirse
de esta forma. En el bus de direcciones original había ya 20 direcciones, ya que con 20
bits se puede dirigir a una memoria de 1 Mb y esto era exactamente lo que correspondía a
la CPU.

Esto que en le teoría parece tan fácil es bastante mas complicado en la práctica, ya que
aparte de los bus de datos y de direcciones existen también casi dos docenas más de
líneas de señal en la comunicación entre la CPU y la memoria, a las cuales también se
acude. Todas las tarjetas del bus escuchan, y se tendrá que encontrar en primer lugar una
tarjeta que mediante el envío de una señal adecuada indique a la CPU que es
responsable de la dirección que se ha introducido. Las demás tarjetas se despreocupan
del resto de la comunicación y quedan a la espera del próximo ciclo de transporte de
datos que quizás les incumba a ellas.

M. D. O. H. Sonia Alvarado Mares


33
Lenguaje Ensamblador

Tabla 1.2 Tamaño de buses de microprocesadores de Intel.

Este mismo concepto es también la razón por la cual al utilizar tarjetas de ampliación en
un PC surgen problemas una y otra vez, si hay dos tarjetas que reclaman para ellas el
mismo campo de dirección o campos de dirección que se solapan entre ellos.

Los datos en si no se mandan al bus de direcciones sino al bus de datos. El bus XT tenía
solo 8 bits con lo cual sólo podía transportar 1 byte a la vez. Si la CPU quería depositar el
contenido de un registro de 16 bits o por valor de 16 bits, tenía que desdoblarlos en dos
bytes y efectuar la transferencia de datos uno detrás de otro.

De todas maneras para los fabricantes de tarjetas de ampliación, cuyos productos deben
atenderse a este protocolo, es de una importancia básica la regulación del tiempo de las
señales del bus, para poder trabajar de forma inmejorable con el PC. Pero precisamente
este protocolo no ha sido nunca publicado por lBM con lo que se obliga a los fabricantes a
medir las señales con la ayuda de tarjetas ya existentes e imitarlas. Por lo tanto no es de
extrañar que se pusieran en juego tolerancias que dejaron algunas tarjetas totalmente
eliminadas.

Estructuras de interconexión.
interconexión.

Existen dos organizaciones físicas de operaciones E/S que tienen que ver con los buses
que son: Bus único y Bus dedicado.

La primera gran diferencia entre estas dos tipos de estructuras es que el bus único no
permite un controlador DMA (todo se controla desde la CPU), mientras que el bus
dedicado si que soporta este controlador.

El bus dedicado trata a la memoria de manera distinta que a los periféricos (utiliza un bus
especial) al contrario que el bus único que los considera a ambos como posiciones de
memoria (incluso equipara las operaciones E/S con las de lectura/escritura en memoria).

Este bus especial que utiliza el bus dedicado tiene 4 componentes fundamentales:

• Datos: Intercambio de información entre la CPU y los periféricos.

M. D. O. H. Sonia Alvarado Mares


34
Lenguaje Ensamblador

• Control: Lleva información referente al estado de los periféricos (petición de


interrupciones).
• Direcciones: Identifica el periférico referido.
• Sincronización: Temporiza las señales de reloj.

La mayor ventaja del bus único es su simplicidad de estructura que le hace ser más
económico, pero no permite que se realice a la vez transferencia de información entre la
memoria y el procesador y entre los periféricos y el procesador.

Por otro lado el bus dedicado es mucho más flexible y permite transferencias simultáneas.
Por contra su estructura es más compleja y por tanto sus costes son mayores.

TIPOS DE BUSES.
BUSES.

Ahora vamos a ver los distintos tipos de buses que se han ido desarrollando y los que se
emplean en la actualidad.

El bus XT y el bus ISA (AT).

Cuando en 1980 IBM fabricó su primer PC, este contaba con un bus de expansión
conocido como XT que funcionaba a la misma velocidad que los procesadores Intel 8086
y 8088 (4.77 Mhz). El ancho de banda de este bus (8 bits) con el procesador 8088
formaba un tandem perfecto, pero la ampliación del bus de datos en el 8086 a 16 bits dejo
en entredicho este tipo de bus (aparecieron los famosos cuellos de botella).

Dada la evolución de los microprocesadores el bus del PC no era ni mucho menos la


solución para una comunicación fluida con el exterior del micro. En definitiva no podía
hablarse de una autopista de datos en un PC cuando esta sólo tenía un ancho de 8 bits.
Por lo tanto con la introducción del AT apareció un nuevo bus en el mundo del PC, que en
relación con el bus de datos tenía finalmente 16 bits (ISA), pero que era compatible con
su antecesor. La única diferencia fue que el bus XT era síncrono y el nuevo AT era
asíncrono. Las viejas tarjetas de 8 bits de la época del PC pueden por tanto manejarse
con las nuevas tarjetas de 16 bits en un mismo dispositivo. De todas maneras las tarjetas
de 16 bits son considerablemente más rápidas, ya que transfieren la misma cantidad de
datos en comparación con las tarjetas de 8 bits en la mitad de tiempo (transferencia de 16
bits en lugar de transferencia de 8 bits).

No tan solo se amplió el bus de datos sino que también se amplió el bus de direcciones,
concretamente hasta 24 bits, de manera que este se podía dirigir al AT con memoria de
16 MB. Además también se aumentó la velocidad de cada una de las señales de
frecuencia, de manera que toda la circulación de bus se desarrollaba más rápidamente.
De 4.77 Mhz en el XT se pasó a 8.33 Mhz. Como consecuencia el bus forma un cuello de
botella por el cual no pueden transferirse nunca los datos entre la memoria y la CPU lo

M. D. O. H. Sonia Alvarado Mares


35
Lenguaje Ensamblador

suficientemente rápido. En los discos duros modernos por ejemplo, la relación (ratio) de
transferencia de datos ya es superior al ratio del bus.

A las tarjetas de ampliación se les ha asignado incluso un freno de seguridad,


concretamente en forma de una señal de estado de espera (wait state), que deja todavía
más tiempo a las tarjetas lentas para depositar los datos deseados en la CPU.

Especialmente por este motivo el bus AT encontró sucesores de más rendimiento en


Micro Channel y en el Bus EISA, que sin embargo, debido a otros motivos, no han tenido
éxito.

Bus Micro Channel (MCA).

Vistas las limitaciones que tenía el diseño del bus ISA en IBM se trabajó en un nueva
tecnología de bus que comercializó con su gama de ordenadores PS/2. El diseño MCA
(Micro Channel Arquitecture) permitía una ruta de datos de 32 bits, más ancha, y una
velocidad de reloj ligeramente más elevada de 10 Mhz, con una velocidad de
transferencia máxima de 20 Mbps frente a los 8 Mbps del bus ISA.

Pero lo que es más importante el novedoso diseño de bus de IBM incluyó un circuito de
control especial a cargo del bus, que le permitía operar independientemente de la
velocidad e incluso del tipo del microprocesador del sistema.

Bajo MCA, la CPU no es más que uno de los posibles dispositivos dominantes del bus a
los que se puede acceder para gestionar transferencias. La circuitería de control, llamada
CAP (punto de decisión central), se enlaza con un proceso denominado control del bus
para determinar y responder a las prioridades de cada uno de los dispositivos que
dominan el bus.

Para permitir la conexión de más dispositivos, el bus MCA especifica interrupciones


sensibles al nivel, que resultan más fiables que el sistema de interrupciones del bus ISA.
De esta forma es posible compartir interrupciones. Pero además se impusieron
estándares de rendimiento superiores en las tarjetas de expansión.

Es cierto que el progreso conlleva un precio: La arquitectura de IBM era totalmente


incompatible con las tarjetas de expansión que se incluyen en el bus ISA. Esto viene
derivado de que los conectores de las tarjetas de expansión MCA eran más pequeños
que las de los buses ISA. De esto se pueden sacar dos conclusiones. Por un lado el coste
de estas tarjetas era menor y por otro ofrecía un mayor espacio interior en las pequeñas
cajas de sobremesa.

Las señales del bus estaban reorganizadas de forma que se introducía una señal de tierra
cada 4 conectores. De esta forma se ayudaba a reducir las interferencias.

EISA (Extended ISA).

El principal rival del bus MCA fue el bus EISA, también basado en la idea de controlar el
bus desde el microprocesador y ensanchar la ruta de datos hasta 32 bits. Sin embargo
EISA mantuvo compatibilidad con las tarjetas de expansión ISA ya existentes lo cual le
M. D. O. H. Sonia Alvarado Mares
36
Lenguaje Ensamblador

obligo a funcionar a una velocidad de 8 Mhz (exactamente 8.33). Esta limitación fue la que
adjudico el papel de estándar a esta arquitectura, ya que los usuarios no veían factible
cambiar sus antiguas tarjetas ISA por otras nuevas que en realidad no podían aprovechar
al 100%.

Su mayor ventaja con respecto al bus MCA es que EISA era un sistema abierto, ya que
fue desarrollado por la mayoría de fabricantes de ordenadores compatibles PC que no
aceptaron el monopolio que intentó ejercer IBM. Estos fabricantes fueron: AST, Compaq,
Epson, Hewlett Packard, NEC, Olivetti, Tandy, Wyse y Zenith.

Esta arquitectura de bus permite multiproceso, es decir, integrar en el sistema varios


buses dentro del sistema, cada uno con su procesador. Si bien esta característica no es
utilizada más que por sistemas operativos como UNIX o Windows NT.

En una máquina EISA, puede haber al mismo tiempo hasta 6 buses principales con
diferentes procesadores centrales y con sus correspondientes tarjetas auxiliares.

En este bus hay un chip que se encarga de controlar el tráfico de datos señalando
prioridades para cada posible punto de colisión o bloqueo mediante las reglas de control
de la especificación EISA. Este chip recibe el nombre de Chip del Sistema Periférico
Integrado (ISP). Este chip actúa en la CPU como un controlador del tráfico de datos.

El motivo para que ni MCA ni EISA hayan sustituido por completo a ISA es muy sencillo:
Estas alternativas aumentaban el coste del PC (incluso más del 50%) y no ofrecían
ninguna mejora evidente en el rendimiento del sistema. Es más, en el momento en que se
presentaron estos buses (1987-1988) esta superioridad en el rendimiento no resultaba
excesivamente necesaria: muy pocos dispositivos llegaban a los límites del rendimiento
del bus ISA ordinario.

Local Bus.

Teniendo en cuenta las mencionadas limitaciones del bus AT y la infalibilidad de los buses
EISA y MCA para asentarse en el mercado, en estos años se han ideado otros conceptos
de bus. Se inició con el llamado Vesa Local Bus (VL-Bus), que fue concebido y propagado
independientemente por el Comité VESA, que se propuso el definir estándares en el
ámbito de las tarjetas gráficas y así por primera vez y realmente tuviera poco que ver con
el diseño del bus del PC. Fueron y son todavía las tarjetas gráficas quienes sufren la
menor velocidad del bus AT. Por eso surgió, en el Comité VESA, la propuesta para un bus
más rápido que fue el VESA Local Bus.

Vesa Local Bus.

Al contrario que con el EISA, MCA y PCI, el bus VL no sustituye al bus ISA sino que lo
complementa. Un PC con bus VL dispone para ello de un bus ISA y de las
correspondientes ranuras (slots) para tarjetas de ampliación. Además, en un PC con bus
VL puede haber, sin embargo, una, dos o incluso tres ranuras de expansión, para la
colocación de tarjetas concebidas para el bus VL, casi siempre gráficos. Solamente estos
slots están conectados con la CPU a través de un bus VL, de tal manera que las otras

M. D. O. H. Sonia Alvarado Mares


37
Lenguaje Ensamblador

ranuras permanecen sin ser molestadas y las tarjetas ISA pueden hacer su servicio sin
inconvenientes.

El VL es una expansión homogeneizada de bus local, que funciona a 32 bits, pero que
puede realizar operaciones a 16 bits.

VESA presentó la primera versión del estándar VL-BUS en agosto de 1992. La aceptación
por parte del mercado fue inmediata. Fiel a sus orígenes, el VL-BUS se acerca mucho al
diseño del procesador 80486. De hecho presenta las mismas necesidades de señal de
dicho chip, exceptuando unas cuantas menos estrictas destinadas a mantener la
compatibilidad con los 386.

La especificación VL-Bus como tal, no establece límites, ni superiores ni inferiores, en la


velocidad del reloj, pero una mayor cantidad de conectores supone una mayor
capacitancia, lo que hace que la fiabilidad disminuya a la par que aumenta la frecuencia.
En la práctica, el VL-BUS no puede superar los 66 Mhz. Por este motivo, la especificación
VL-BUS original recomienda que los diseñadores no empleen más de tres dispositivos de
bus local en sistemas que operan a velocidades superiores a los 33 Mhz. A velocidades
de bus superiores, el total disminuye: a 40 Mhz solo se pueden incorporar dos
dispositivos; y a 50 Mhz un único dispositivo que ha de integrarse en la placa. En la
práctica, la mejor combinación de rendimiento y funciones aparece a 33 Mhz.

Tras la presentación del procesador Pentium a 64 bits, VESA comenzó a trabajar en un


nuevo estándar (VL-Bus versión 2.0).

La nueva especificación define una interface de 64 bits pero que mantienen toda
compatibilidad con la actual especificación VL-BUS. La nueva especificación 2.0 redefine
además la cantidad máxima de ranuras VL-BUYS que se permiten en un sistema sencillo.
Ahora consta de hasta tres ranuras a 40 Mhz y dos a 50 Mhz, siempre que el sistema
utilice un diseño de baja capacitancia.

En el nombre del bus VL queda de manifiesto que se trata de un bus local. De forma
distinta al bus ISA éste se acopla directamente en la CPU. Esto le proporciona por un lado
una mejora substancial de la frecuencia de reloj (de la CPU) y hace que dependa de las
líneas de control de la CPU y del reloj. A estas desventajas hay que añadirle que no en
todos los puntos están bien resueltas las especificaciones del comité VESA, hecho que a
la larga le llevará a que el éxito del bus VL se vea empañado por ello. En sistemas 486
económicos se podía encontrar a menudo, pero su mejor momento ya ha pasado.

PCI (Peripheral Component Interconnect).


Interconnect).

Visto lo anterior, se puede ver que el bus del futuro es claramente el PCI de Intel. PCI
significa: interconexión de los componentes periféricos (Peripheral Component
Interconnect) y presenta un moderno bus que no sólo está meditado para no tener la
relación del bus ISA en relación a la frecuencia de reloj o su capacidad sino que también
la sincronización con las tarjetas de ampliación en relación a sus direcciones de puerto,
canales DMA e interrupciones, se ha automatizado finalmente de tal manera que el
usuario no deberá preocuparse más por ello.

M. D. O. H. Sonia Alvarado Mares


38
Lenguaje Ensamblador

El bus PCI es independiente de la CPU, ya que entre la CPU y el bus PCI se instalará
siempre un controlador de bus PCI, lo que facilita en gran medida el trabajo de los
diseñadores de placas. Por ello también será posible instalarlo en sistemas que no estén
basados en el procesador Intel si no que pueden usar otros, como por ejemplo, un
procesador Alpha de DEC. También los procesadores PowerMacintosh de Apple se
suministran en la actualidad con bus PCI.

Las tarjetas de expansión PCI trabajan eficientemente en todos los sistemas y pueden ser
intercambiadas de la manera que se desee. Solamente los controladores de dispositivo
deben naturalmente ser ajustados al sistema anfitrión (host) es decir a su correspondiente
CPU.

Como vemos el bus PCI no depende del reloj de la CPU, porque está separado de ella
por el controlador del bus. Si se instalara una CPU más rápida en su ordenador no
debería preocuparse porque las tarjetas de expansión instaladas no pudieran soportar las
frecuencias de reloj superiores, pues con la separación del bus PCI de la CPU éstas no
son influidas por esas frecuencias de reloj. Así se ha evitado desde el primer momento
este problema y defecto del bus VL.

El bus PCI emplea un conector estilo Micro Channel de 124 pines (188 en caso de una
implementación de 64 bits) pero únicamente 47 de estas conexiones se emplean en una
tarjeta de expansión (49 en caso de que se trate de un adaptador bus-master); la
diferencia se debe a la incorporación de una línea de alimentación y otra de tierra. Cada
una de las señales activas del bus PCI está bien junto o frente a una señal de
alimentación o de tierra, una técnica que minimiza la radiación.

El límite práctico en la cantidad de conectores para buses PCI es de tres; como ocurre
con el VL, más conectores aumentarían la capacitancia del bus y las operaciones a
máxima velocidad resultarían menos fiables.

A pesar de presentar un rendimiento similar al de un bus local conectado directamente, en


realidad PCI no es más que la eliminación de un paso en el microprocesador. En lugar de
disponer de su propio reloj, un bus PCI se adapta al empleado por el microprocesador y
su circuitería, por tanto los componentes del PCI están sincronizados con el procesador.
El actual estándar PCI autoriza frecuencias de reloj que oscilan entre 20 y 33 Mhz.

A pesar que de que las tarjetas ISA no pueden ser instaladas en una ranura PCI, no
debería renunciarse a la posibilidad de inserción de una tarjeta ISA. Así pues, a menudo
se puede encontrar en un equipo con bus PCI la interfaz «puente» llamada «PCI-To-ISA-
Bridge». Se trata de un chip que se conecta entre los distintos slots ISA y el controlador
del bus PCI. Su tarea consiste en transponer las señales provenientes del bus PCI al bus
ISA. De esta manera pueden seguir siendo utilizadas las tarjetas ISA al amparo del bus
PCI.

A pesar de que el bus PCI es el presente, sigue habiendo buses y tarjetas de expansión
ISA ya que no todas las tarjetas de expansión requieren las ratios de transferencia que
permite el bus PCI. Sin embargo las tarjetas gráficas, tarjetas SCSI y tarjetas de red se
han decantando cada vez más fuertemente hacia el bus PCI. La ventaja de la velocidad
de este sistema de bus es que este hardware puede participar del continuo incremento de
velocidad de los procesadores.

M. D. O. H. Sonia Alvarado Mares


39
Lenguaje Ensamblador

1.2.2 Registros.

Arquitectura de los procesadores 8088 y 8086.

El 8086 es un microprocesador de 16 bits, tanto en lo que se refiere a su estructura como


en sus conexiones externas, mientras que el 8088 es un procesador de 8 bits que
internamente es casi idéntico al 8086. La única diferencia entre ambos es el tamaño del
bus de datos externo. Intel trata esta igualdad interna y desigualdad externa dividiendo
cada procesador 8086 y 8088 en dos sub-procesadores. O sea, cada uno consta de una
unidad de ejecución (EU: Execution Unit) y una unidad interfaz del bus (BIU: Bus Interface
Unit).

La unidad de ejecución es la encargada de realizar todas las operaciones mientras que la


unidad de interfaz del bus es la encargada de acceder a datos e instrucciones del mundo
exterior. Las unidades de ejecución son idénticas en ambos microprocesadores, pero las
unidades de interfaz del bus son diferentes en varias cuestiones, como se desprende del
siguiente diagrama en bloques:

La ventaja de esta división fue el ahorro de esfuerzo necesario para producir el 8088. Sólo
una mitad del 8086 (el BIU) tuvo que rediseñarse para producir el 8088.

La explicación del diagrama en bloques, de la figura 1.2 es la siguiente:

Registros de uso general del 8086/8088:

Tienen 16 bits cada uno y son ocho:

1. AX = Registro acumulador, dividido en AH y AL (8 bits cada uno).

M. D. O. H. Sonia Alvarado Mares


40
Lenguaje Ensamblador

Usándolo se produce (en general) una instrucción que ocupa un byte menos que si
se utilizaran otros registros de uso general. Su parte más baja, AL, también tiene
esta propiedad. El último registro mencionado es el equivalente al acumulador de
los procesadores anteriores (8080 y 8085). Además hay instrucciones como DAA;
DAS; AAA; AAS; AAM; AAD; LAHF; SAHF; CBW; IN y OUT que trabajan con AX o
con uno de sus dos bytes (AH o AL). También se utiliza este registro (junto con DX
a veces) en multiplicaciones y divisiones.

2. BX = Registro base, dividido en BH y BL.


Es el registro base de propósito similar (se usa para direccionamiento indirecto) y
es una versión más potente del par de registros HL de los procesadores
anteriores.

3. CX = Registro contador, dividido en CH y CL.


Se utiliza como contador en bucles (instrucción LOOP), en operaciones con
cadenas (usando el prefijo REP) y en desplazamientos y rotaciones (usando el
registro CL en los dos últimos casos).

M. D. O. H. Sonia Alvarado Mares


41
Lenguaje Ensamblador

Figura 1.2. Arquitectura de los procesadores 8088 y 8086.

4. DX = Registro de datos, dividido en DH y DL.


Se utiliza junto con el registro AX en multiplicaciones y divisiones, en la instrucción
CWD y en IN y OUT para direccionamiento indirecto de puertos (el registro DX
indica el número de puerto de entrada/salida).

5. SP = Puntero de pila (no se puede subdividir).

M. D. O. H. Sonia Alvarado Mares


42
Lenguaje Ensamblador

Aunque es un registro de uso general, debe utilizarse sólo como puntero de pila, la
cual sirve para almacenar las direcciones de retorno de subrutinas y los datos
temporarios (mediante las instrucciones PUSH y POP). Al introducir (push) un
valor en la pila a este registro se le resta dos, mientras que al extraer (pop) un
valor de la pila este a registro se le suma dos.

6. BP = Puntero base (no se puede subdividir).


Generalmente se utiliza para realizar direccionamiento indirecto dentro de la pila.

7. SI = Puntero índice (no se puede subdividir).


Sirve como puntero fuente para las operaciones con cadenas. También sirve para
realizar direccionamiento indirecto.

8. DI = Puntero destino (no se puede subdividir).


Sirve como puntero destino para las operaciones con cadenas. También sirve para
realizar direccionamiento indirecto.

Cualquiera de estos registros puede utilizarse como fuente o destino en operaciones


aritméticas y lógicas, lo que no se puede hacer con ninguno de los seis registros que se
verán más adelante. Además de lo anterior, cada registro tiene usos especiales.

Unidad aritmética y lógica.

Es la encargada de realizar las operaciones aritméticas (suma, suma con "arrastre", resta,
resta con "préstamo" y comparaciones) y lógicas (AND, OR, XOR y TEST). Las
operaciones pueden ser de 16 bits o de 8 bits.

Indicadores (flags
(flags).
).

Hay nueve indicadores de un bit en este registro de 16 bits. Los cuatro bits más
significativos están indefinidos, mientras que hay tres bits con valores determinados: los
bits 5 y 3 siempre valen cero y el bit 1 siempre vale uno (esto también ocurría en los
procesadores anteriores).

Registro de indicadores (16 bits)


Bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Flag -- -- -- -- OF DF IF TF SF ZF 0 AF 0 PF 1 CF

• CF (Carry Flag, bit 0): Si vale 1, indica que hubo "arrastre" (en caso de suma)
hacia, o "préstamo" (en caso de resta) desde el bit de orden más significativo del
resultado. Este indicador es usado por instrucciones que suman o restan números
que ocupan varios bytes. Las instrucciones de rotación pueden aislar un bit de la
memoria o de un registro poniéndolo en el CF.

M. D. O. H. Sonia Alvarado Mares


43
Lenguaje Ensamblador

• PF (Parity Flag, bit 2): Si vale uno, el resultado tiene paridad par, es decir, un
número par de bits a 1. Este indicador se puede utilizar para detectar errores en
transmisiones.

• AF (Auxiliary carry Flag, bit 4): Si vale 1, indica que hubo "arrastre" o "préstamo"
del nibble (cuatro bits) menos significativo al nibble más significativo. Este indicador
se usa con las instrucciones de ajuste decimal.

• ZF (Zero Flag, bit 6): Si este indicador vale 1, el resultado de la operación es cero.

• SF (Sign Flag, bit 7): Refleja el bit más significativo del resultado. Como los
números negativos se representan en la notación de complemento a dos, este bit
representa el signo: 0 si es positivo, 1 si es negativo. (de -128 a 127 para números
con signo y sin signo de 0 a 255)

• TF (Trap Flag, bit 8): Si vale 1, el procesador está en modo paso a paso. En este
modo, la CPU automáticamente genera una interrupción interna después de cada
instrucción, permitiendo inspeccionar los resultados del programa a medida que se
ejecuta instrucción por instrucción.

• IF (Interrupt Flag, bit 9): Si vale 1, la CPU reconoce pedidos de interrupción


externas enmascarables (por el pin INTR). Si vale 0, no se reconocen tales
interrupciones. Las interrupciones no enmascarables y las internas siempre se
reconocen independientemente del valor de IF.

• DF (Direction Flag, bit 10): Si vale 1, las instrucciones con cadenas sufrirán "auto-
decremento", esto es, se procesarán las cadenas desde las direcciones más altas
de memoria hacia las más bajas. Si vale 0, habrá "auto-incremento", lo que quiere
decir que las cadenas se procesarán de "izquierda a derecha".

• OF (Overflow flag, bit 11): Si vale 1, hubo un desborde en una operación


aritmética con signo, esto es, un dígito significativo se perdió debido a que tamaño
del resultado es mayor que el tamaño del destino.

Sistema de control de la unidad de ejecución.

Es el encargado de decodificar las instrucciones que le envía la cola y enviarle las


órdenes a la unidad aritmética y lógica según una tabla que tiene almacenada en ROM
llamada CROM (Control Read Only Memory).

Cola de instrucciones.

Almacena las instrucciones para ser ejecutadas. La cola se carga cuando el bus está
desocupado, de esta manera se logra una mayor eficiencia del mismo. La cola del 8086
tiene 6 bytes y se carga de a dos bytes por vez (debido al tamaño del bus de datos),
mientras que el del 8088 tiene cuatro bytes. Esta estructura tiene rendimiento óptimo
cuando no se realizan saltos, ya que en este caso habría que vaciar la cola (porque no se
van a ejecutar las instrucciones que van después del salto) y volverla a cargar con

M. D. O. H. Sonia Alvarado Mares


44
Lenguaje Ensamblador

instrucciones que se encuentran a partir de la dirección a donde se salta. Debido a esto


las instrucciones de salto son (después de multiplicaciones y divisiones) las más lentas de
este microprocesador.

Registros de la unidad de interfaz con el bus.

El programador puede acceder a cinco registros de 16 bits cada uno, siendo cuatro de
ellos registros de segmento y el restante el puntero de instrucción (IP).

Los registros de segmento se llaman:

• CS (Code Segment) o registro de segmento de código. El DOS almacena la


dirección inicial del segmento de código de un programa en el registro CS. Está
dirección de segmento, más un valor de desplazamiento en el registro de
apuntador de instrucción (IP), indica la dirección de una instrucción que es buscada
para su ejecución. Para propósitos de programación normal, no se necesita
referenciar el registro CS.

• DS (Data Segment) o registro de segmento de datos. La dirección inicial de un


segmento de datos de programa es almacenada en el registro DS. En términos
sencillos, está dirección, más un valor de desplazamiento en esta instrucción,
genera una referencia a la localidad de un byte específico en el segmento de datos.

• ES (Extra Segment) o registro de segmento extra. Algunas operaciones con


cadenas de caracteres (datos de caracteres) utilizan el registro extra del segmento
para manejar el direccionamiento de memoria. En este contexto, el registro ES esta
asociado con el registro DI (índice). Un programa que requiere el uso del registro
ES puede inicializarlo con una dirección de segmento apropiada.

• SS (Stack Segment) o registro de segmento de pila. El registro SS permite la


colocación en memoria de una pila, para almacenamiento temporal de direcciones
y datos. El DOS almacena la dirección de inicio del segmento de pila de un
programa en el registro SS. Esta dirección de segmento, más un valor de
desplazamiento en el registro del apuntador de la pila (SP), indica la palabra actual
en la pila que está siendo direccionada. Para propósitos de programación normal,
no se necesita referenciar el registro SS.

• IP (Pointer Instruction) o registro de apuntador de instrucciones. Contiene el


desplazamiento de dirección de la siguiente instrucción que se ejecuta. El IP está
asociado con el registro CS en el sentido de que el IP indica la instrucción actual
dentro del segmento de código que se esta ejecutando actualmente. Por lo común,
usted no refiere el registro IP en un programa, pero, para probar un programa, si
puede cambiar su valor por medio del programa DEBUG del DOS. Los
procesadores 80386 y posteriores tienen un IP ampliado de 32 bits, llamado EIP.

Los registros anteriores son primordiales para generar la dirección de 20 bits que se
pondrá en el bus de direcciones de la CPU. Cualquier operación que accede la memoria
usará forzosamente uno de estos registros.

M. D. O. H. Sonia Alvarado Mares


45
Lenguaje Ensamblador

Lógica de control del bus.

El cometido de este bloque es poder unir los bloques anteriormente mencionados con el
mundo exterior, es decir, la memoria y los periféricos.

El 8088 tiene un bus de datos externo reducido de 8 bits. La razón para ello era prever la
continuidad entre el 8086 y los antiguos procesadores de 8 bits, como el 8080 y el 8085.
Teniendo el mismo tamaño del bus (así como similares requerimientos de control y
tiempo), el 8088, que es internamente un procesador de 16 bits, puede reemplazar a los
microprocesadores ya nombrados en un sistema ya existente.

El 8088 tiene muchas señales en común con el 8085, particularmente las asociadas con
la forma en que los datos y las direcciones están multiplexadas, aunque el 8088 no
produce sus propias señales de reloj como lo hace el 8085 (necesita un chip de soporte
llamado 8284, que es diferente del 8224 que necesitaba el microprocesador 8080). El
8088 y el 8085 siguen el mismo esquema de compartir los terminales correspondientes a
los 8 bits más bajos del bus de direcciones con los 8 bits del bus de datos, de manera que
se ahorran 8 terminales para otras funciones del microprocesador. El 8086 comparte los
16 bits del bus de datos con los 16 más bajos del bus de direcciones.

El 8085 y el 8088 pueden, de hecho, dirigir directamente los mismos chips controladores
de periféricos. Las investigaciones de hardware para sistemas basados en el 8080 o el
8085 son, en su mayoría, aplicables al 8088. En todo lo recién explicado se basó el éxito
del 8088.

M. D. O. H. Sonia Alvarado Mares


46
Lenguaje Ensamblador

1.2.3 Modos de direccionamiento.

Introducción.
Introducción.

El campo de operación de una instrucción especifica la operación que se debe realizar.


Esta debe ser ejecutada sobre algunos datos almacenados en registros del computador o
en palabras de memoria, es decir, sobre los operandos. El modo de direccionamiento
especifica la forma de interpretar la información contenida en cada campo de operando
para localizar, en base a esta información, el operando.

Los ordenadores utilizan técnicas de direccionamiento con los siguientes fines:

• Dar versatilidad de programación al usuario proporcionando facilidades tales como


índices, direccionamientos indirectos, etc., esta versatilidad nos servirá para
manejar estructuras de datos complejas como vectores, matrices, etc.

• Reducir el número de bits del campo de operando.

Al usuario que tiene poca experiencia, la variedad de modos de direccionamiento en un


ordenador le puede parecer excesivamente complicada. Sin embargo, la disponibilidad de
diferentes esquemas de direccionamiento le da al programador experimentado flexibilidad
para escribir programas que son más eficientes en cuanto a número de instrucciones y
tiempo de ejecución.

Es tal la importancia de los modos de direccionamiento que la potencia de una máquina


se mide tanto por su repertorio de instrucciones como por la variedad de modos de
direccionamiento que es capaz de admitir.

Definición: Los modos de direccionamiento de un ordenador son las diferentes formas de


transformación del campo de operando de la instrucción en la dirección del operando.

En esta definición el término dirección debe interpretarse en su sentido más general de


localización del operando, en cualquier lugar, y no en el sentido más estricto de dirección
de memoria.

A la dirección obtenida de las transformaciones anteriores la llamaremos dirección


efectiva. Esta dirección, en el caso de tratarse de una dirección de memoria, es la que se
cargará en el M.A.R. o registro de dirección de memoria.

Llamando x a la información del campo de operando y Aef. a la dirección efectiva, la


función f que a partir de x nos da Aef. constituirá el modo de direccionamiento empleado:

Aef. = f(x).

M. D. O. H. Sonia Alvarado Mares


47
Lenguaje Ensamblador

En la evaluación de la función f pueden intervenir otras informaciones además de la


información presente en el campo de operando de la instrucción. Estas informaciones
pueden residir en registros del procesador o en memoria.

La especificación del modo de direccionamiento puede ir en el código de operación o en


el campo de cada operando. Normalmente se codifica en el código de operación si el
número de modos es pequeño, en caso contrario se codifica con cada operando, esta
última forma de codificación favorece la ortogonalidad.

Modos de direccionamiento más usuales.

En los párrafos siguientes se irán describiendo los modos de direccionamiento más


frecuentes. La mayoría de estos modos son comunes a muchas máquinas, sin embargo,
hay otros que sólo se usan en determinados procesadores.

Direccionamiento implícito.

En este modo, llamado también inherente, el operando se especifica en la misma


definición de la instrucción. El modo implícito se usa para hacer referencia a operandos de
dos tipos:

• Registros: En el caso de que el código de operación se refiera en particular a un


registro.

• Operandos en la pila: En el caso de que la operación se realice siempre sobre el


dato situado en la cima de pila.

El primer caso es típico de las organizaciones de un solo acumulador. Generalmente en


un ordenador de este tipo todas las instrucciones que actúan sobre el acumulador utilizan
direccionamiento implícito. Ejemplo: MOV AX, BX.

En el segundo caso están la mayoría de las instrucciones de los ordenadores con


organización de pila. Estas operaciones llevan implícitos los operandos que son los
elementos de la cima de pila. Esto se debe a que en este tipo de máquinas la mayoría de
las operaciones no tienen campos de dirección. También están en este caso las
instrucciones PUSH y POP de la mayoría de los ordenadores cuyo operando implícito
también es, como en el caso anterior, la cima de pila. Ejemplo: PUSH AX.

Direccionamiento inmediato (o literal).

En este modo es el operando el que figura en la instrucción no su dirección. En otras


palabras el campo de operando contiene él mismo, sin transformación alguna, la
información sobre la que hay que operar. Este modo es útil para inicializar registros o
palabras de memoria con un valor constante. Ejemplo: MOV AX, 5.

Direccionamiento directo por registro.

M. D. O. H. Sonia Alvarado Mares


48
Lenguaje Ensamblador

Se mencionó anteriormente que el campo de dirección de una instrucción puede


especificar una palabra de memoria o un registro del procesador. Cuando se da este
último caso se dice que el operando está especificado con direccionamiento directo por
registro, en tal caso, el operando reside en uno de los registros del procesador que es
seleccionado por un campo de registro de k bits en la instrucción. Un campo de k bits
puede especificar uno de 2k registros. Este modo es típico de los ordenadores con
organización de registros de uso general.
Las ventajas de este modo son:

• El acceso a los registros es muy rápido, por tanto el direccionamiento por registro
debe usarse en las variables que se usen con más frecuencia para evitar accesos
a memoria que son más lentos, un ejemplo muy típico del uso de este
direccionamiento son los índices de los bucles.

• El número de bits necesarios para especificar un registro es mucho más pequeño


que el necesario para especificar una dirección de memoria, esto es debido a que
el número de registros del procesador es muy pequeño comparado con el número
de direcciones de memoria. Sin embargo, hay que tener en cuenta que en los
ordenadores modernos el número de registros ha aumentado considerablemente.

Direccionamiento directo (o absoluto).

Este es el modo de direccionamiento más sencillo. El campo de dirección no necesita


transformación alguna para dar la dirección efectiva, es decir la función que transforma el
campo de operando en la dirección efectiva es la identidad. Esto significa que el campo
de operando es ya la dirección efectiva.

Este direccionamiento sólo se usa en ordenadores pequeños en que el programa siempre


se sitúa en la misma zona de memoria ya que dificulta la relocalización de los programas,
es decir que el código de los programas no dependa de su situación en memoria.
Ordinariamente este modo sólo se usa para acceder a direcciones del sistema que
normalmente se refieren a operaciones de entrada y salida ya que estas direcciones no
dependen del programa. Ejemplo: MOV AX, VALOR, donde VALOR es una localidad de
memoria donde se encuentra alguna información que será movida al registro AX. VALOR
es considerado una variable dentro del programa. Otro ejemplo sería MOV AX, [200H],
donde [200H] representa el contenido de la localidad 200H.

Direccionamiento indirecto.

En este modo el campo de operando de la instrucción indica la localización de la dirección


efectiva del operando. El modo de direccionamiento indirecto puede adquirir diferentes
formas según cuál sea el lugar donde se encuentre la dirección del operando. En general,
todos los modos de direccionamiento tienen su versión indirecta que añade un eslabón
más a la cadena del direccionamiento. Por ejemplo existe el direccionamiento indirecto
por registro, en el que el registro especificado contiene la dirección del operando, no el
operando mismo.

Este direccionamiento es útil cuando se trabaja con punteros ya que los punteros son
variables que contienen las direcciones de los operandos, no los operandos mismos.
Ejemplo: MOV AX, [SI], esta instrucción toma el contenido del registro SI como una

M. D. O. H. Sonia Alvarado Mares


49
Lenguaje Ensamblador

localidad de memoria, accesa dicha localidad, obtiene el valor que se encuentra en ella y
lo mueve al registro AX.

Direccionamiento relativo.

Hay algunos modos de direccionamiento en que se hace uso de una propiedad muy
generalizada de los programas denominada localidad de referencia, esta propiedad
consiste en que las direcciones referenciadas por los programas no suelen alejarse
mucho unas de otras y, por tanto, suelen estar concentradas en una parte de la memoria.

Estas consideraciones nos llevan a la conclusión de que no es necesario utilizar todos los
bits de la dirección de memoria en el campo de operando, basta utilizar los bits precisos
para cubrir la parte de memoria donde estén incluidas las direcciones a las que el
programa hace referencia. Esto puede hacerse tomando como referencia un punto de la
memoria y tomando como campo de operando la diferencia entre ese punto y la dirección
efectiva del operando. La dirección que se toma como punto de referencia puede residir
en un registro de la CPU y, por tanto, sumando el contenido de ese registro con el campo
de operando obtendremos la dirección efectiva. Hay varios direccionamientos basados en
esta técnica que reciben diferentes nombres dependiendo de cuál sea el registro en el
que radica la dirección tomada como referencia. Todos ellos podrían catalogarse como
direccionamientos relativos a un registro.

El direccionamiento denominado habitualmente relativo toma como valor de referencia el


registro contador de programa. Cuando se usa este modo de direccionamiento, el campo
de operando consiste en un número (normalmente con signo) que expresa la diferencia
entre la dirección del dato y la dirección siguiente a la instrucción en curso (contenida en
el contador de programa). Si el campo de operando, llamado en este caso
desplazamiento u offset, es positivo el operando residirá en una dirección posterior a la de
la instrucción y si es negativo, en una dirección anterior.

Este modo de direccionamiento es usado muy frecuentemente en programas cuyo código


deba ser independiente de la posición de memoria donde estén situados (programas
relocalizables) ya que el desplazamiento es independiente de la localización del
programa. También se usa con mucha frecuencia en instrucciones de bifurcación.

Los apartados siguientes se refieren a diferentes versiones de direccionamientos relativos


a registros.

Direccionamiento por base y desplazamiento.

Este modo de direccionamiento se fundamenta en la propiedad de localidad de referencia


mencionada anteriormente. La dirección que se toma como referencia de la zona de
memoria en la que están localizados los datos se deposita en un registro denominado
registro base y el campo de operando indica la diferencia entre el registro base y la
dirección del operando. Normalmente se toma como referencia (registro base) la dirección
de comienzo de la zona de memoria ocupada por un programa. Por tanto, la dirección

M. D. O. H. Sonia Alvarado Mares


50
Lenguaje Ensamblador

efectiva del operando se calculará sumando el contenido del registro base con el campo
de operando.

Este modo de direccionamiento se usa en ordenadores que pueden mantener en memoria


varios programas ya que, de esta forma, los diferentes registros base pueden contener las
direcciones de comienzo de cada uno de los programas. Esto es muy útil porque facilita la
relocalización de los programas para situar el programa en una zona de memoria
diferente bastará con cambiar el contenido de su registro base, no será necesario cambiar
ninguno de los campos de operando.

Direccionamiento indexado

En este modo de direccionamiento, la dirección del operando también se calcula sumando


un registro de la CPU al campo de operando, este registro es un registro específico para
este uso llamado registro índice. En los ordenadores con organización de registros
generales, el registro índice puede ser cualquiera de los registros de la CPU. En los
ordenadores en que el contador de programa es considerado como un registro de uso
general (PDP 11 y VAX) el modo relativo es un caso particular del direccionamiento
indexado. A la cantidad que hay que sumar al registro índice para conseguir la dirección
del operando también se le llama desplazamiento u offset.

Este modo de direccionamiento es especialmente útil para el direccionamiento de


vectores y matrices en bucles ya que, si se quieren direccionar elementos consecutivos
del vector o matriz, basta mantener en el desplazamiento la dirección del primer elemento
e ir incrementando el registro índice. También sirve para acceder de forma relativa a
elementos de vectores cercanos a uno dado, para ello, se carga la dirección del elemento
de referencia en el registro índice y después se accede mediante direccionamiento
indexado, con el desplazamiento adecuado, al anterior, al siguiente, etc., esto mismo
también es aplicable a pilas, en que, en ocasiones, hay que acceder a datos cercanos,
por encima o por debajo, al dato señalado por algún apuntador.

Una consecuencia de todo esto es una modalidad de direccionamiento indexado de que


disponen algunos ordenadores, denominada autoindexación, que hace que el registro
índice sea incrementado o decrementado en el tamaño del operando antes o después de
acceder al mismo. Los ordenadores que poseen autoindexación incorporan los modos de
direccionamiento descritos en los dos apartados siguientes. En algunos ordenadores
existen variantes del direccionamiento indexado en que se obtiene la dirección del
operando sumando el contenido de varios registros con el desplazamiento, esto puede
servir para especificar el comienzo de un vector mediante un desplazamiento respecto a
un registro y el elemento del vector mediante un registro índice.

Direccionamiento autoincremental o postincremental.

En este modo, la dirección del operando se encuentra en un registro y éste es


incrementado, después de acceder al operando, en el tamaño del mismo.

Este modo es útil para manejar vectores y matrices como se veía en el apartado anterior.
También se puede utilizar para extraer datos de pilas (que crezcan hacia direcciones
bajas) ya que, si el registro sobre el que se aplica este modo es el apuntador de pila,
después de la operación el apuntador señalará al siguiente elemento de la pila.

M. D. O. H. Sonia Alvarado Mares


51
Lenguaje Ensamblador

Direccionamiento autodecremental o predecremental.

En este modo para obtener la dirección del operando hay que decrementar un registro en
el tamaño del operando; el nuevo contenido del registro después de efectuar esa
operación, es la dirección del operando.

1.3 INTERRUPCIONES.

Una interrupción es un mecanismo de transferencia de control; básicamente ocasiona que


la CPU detenga la ejecución del programa actual, transfiera el control a una rutina de
servicio, y al término de esta prosiga con la ejecución del programa interrumpido.

La familia de microprocesadores compatibles con Intel acepta dos tipos de interrupciones,


las de hardware y las de software. Las interrupciones de hardware son invocadas
asíncronamente (es decir, pueden ocurrir en cualquier momento y no se encuentran bajo
el control del programa) por un dispositivo o evento externo, por ejemplo la pulsación de
una tecla, la recepción de un byte en alguno de los puertos disponibles o la ocurrencia de
un error de paridad (error de memoria que generalmente no tiene remedio). En el caso del
teclado, cuando se oprime alguna tecla, el hardware del teclado envía una señal a la CPU
para indicarle que detenga inmediatamente lo que esté haciendo e invoque a alguna de
las rutinas del BIOS, la cual atenderá la solicitud de interrupción y al terminar regresará el
control a la CPU para que ésta a su vez continúe con lo que estaba realizando.

Por otro lado, las interrupciones de software en realidad no interrumpen algo sino más
bien son una variante de las rutinas, las cuales pueden invocarse a voluntad y son
controladas por el programa en forma síncrona (o sea que se conoce todo lo relacionado
con su ejecución, pues el programa controla el momento y la manera en que son
invocadas) mediante la secuencia de instrucciones Call y Ret. Sin embargo, para
interrupciones de software mediante la instrucción Int num de la interrupción (pero siguen
siendo operaciones síncronas).

Cuando la CPU está lista para atender a quien la interrumpió, pasa el control a una rutina
llamada Manejador de interrupciones. Esta rutina define la causa de la interrupción,
proporciona el servicio solicitado y regresa el control a la CPU para que ésta pueda
proseguir con lo que estaba haciendo antes.

Como ya se dijo, la mayoría de las interrupciones son causadas por eventos externos a la
CPU, como por ejemplo:

• Necesidad de terminar un proceso de entrada/salida.


• Recepción de datos en alguno de los puertos disponibles (serial o paralelo).
• Detección de un problema en el hardware.
• Una división entre cero.
• Una pulsación en el teclado.
• Una operación de lectura/escritura sobre el (los) disco (s).

Para que puedan dar un servicio adecuado a las interrupciones, la mayoría de los
procesadores usan diferentes niveles de interrupción. Para cada nivel existe una
M. D. O. H. Sonia Alvarado Mares
52
Lenguaje Ensamblador

secuencia de localidades en memoria, las cuales contienen el segmento y el


desplazamiento de la dirección donde se encuentra el manejador de la interrupción. Esta
secuencia de localidades se denomina Tabla de vectores de interrupción, y se encuentra
en los primeros 1024 bytes de la memoria baja a partir de 0:0 (segmento 0,
desplazamiento 0). El segmento y el desplazamiento ocupan 4 bytes dentro de la tabla,
estando primero la palabra baja y después la alta; es decir, primero se almacena el
desplazamiento y después el segmento (dos bytes cada uno).

Pasos durante una interrupción.

• El CPU suspende lo que estaba realizando. El hardware transfiere el control al


sistema de operación.

• Deshabilita las interrupciones. Mientras se atiende una interrupción no se


puede atender otra que llegue. Algunas arquitecturas con manejo de
interrupciones sofisticadas permiten, mediante un esquema de prioridades,
interrumpir un servicio de interrupción para atender otra de mayor prioridad.
Aquellas interrupciones de menor o igual prioridad son deshabilitadas.

• El kernel del sistema de operación salva el estado actual del proceso


interrumpido.

• Transfiere su ejecución a una dirección fija. Esta dirección por lo general


contiene la dirección de comienzo donde la rutina de servicio de la interrupción
se encuentra. Cada dise�o de computador tiene su propio mecanismo de
interrupciones. Una forma de manejar las interrupciones es invocando una
rutina general que examine la información de la interrupción y determine el tipo
de interrupción ocurrida, y de alli llama a la rutina que se encarga de atender
dicha interrupción. Por lo general se maneja mediante un vector de
interrupciones, indexado por el tipo de interrupción. En este vector se
encuentra la dirección de comienzo de la rutina que da servicio a dicho tipo. Se
le conoce como vector de interrupción. Otra forma de localizar la rutina
apropiada es mediante el pooling, es decir, preguntando a cada dispositivo
pare ver quien requirió el servicio.

• Se ejecuta la rutina de interrupción.

• Se restaura el estado anterior.

• Se habilitan las interrupciones.

• La arquitectura de interrupciones debe también almacenar la dirección de la


instrucción interrumpida.

Los sistemas de operación modernos operan por interrupciones (interrupt driven). Es


decir, el sistema de operación estará ocioso esperando a que algún evento ocurra
(proceso a ejecutar, servicio de E/S, etc). Los eventos son indicados por la ocurrencia de
una interrupción o trap. Un trap es una excepción causada por software.

M. D. O. H. Sonia Alvarado Mares


53
Lenguaje Ensamblador

Eventos de una interrupción.

Cuando la CPU es interrumpida empuja a la pila el registro de banderas, el registro de


segmento de código (CS) y el apuntador de instrucciones (IP), además de que se
deshabilita el sistema de interrupciones.

Enseguida usa el número de 8 bits puesto en el bus del sistema por quien intenta
interrumpir a la CPU, y calcula la dirección en formato segmento:desplazamiento del
manejador que se encuentra en memoria baja ( # de interrupción * 4).

Una vez teniendo la dirección del vector, le pasa el control a éste y la ejecución continúa
en este punto. Al recibir el control, el manejador, habilita las interrupciones, guarda los
registros que va a usar, procesa la interrupción y finalmente restaura el contenido original
de las banderas y de los registros CS e IP mediante la instrucción Iret.

Algunos dispositivos, los que están canalizados por el PIC, necesitan mandarle una señal
de Fin de interrupción (End Of Interrupt, EOI) al mismo PIC mediante su puerto de control.
Esto tiene como propósito indicarle al circuito que ya se terminó de procesar la
interrupción y que todo está bien.

M. D. O. H. Sonia Alvarado Mares


54
Lenguaje Ensamblador

1.3.1 Hardware.

Interrupciones internas de hardware.

Las interrupciones internas son generadas por ciertos eventos que surgen durante la
ejecución de un programa.

Este tipo de interrupciones son manejadas en su totalidad por el hardware y no es posible


modificarlas.

Un ejemplo claro de este tipo de interrupciones es la que actualiza el contador del reloj
interno de la computadora, el hardware hace el llamado a esta interrupción varias veces
durante un segundo para mantener la hora actualizada.

Aunque no podemos manejar directamente esta interrupción (no podemos controlar por
software las actualizaciones del reloj), es posible utilizar sus efectos en la computadora
para nuestro beneficio, por ejemplo para crear un "reloj virtual" actualizado continuamente
gracias al contador del reloj interno. Únicamente debemos escribir un programa que lea el
valor actual del contador y lo traduzca a un formato entendible para el usuario.

Interrupciones externas de hardware.

Estas interrupciones en su mayoría son generadas por los periféricos y/o por los
coprocesadores. Estos dispositivos pueden estar conectados a la patilla NMI o INTR de la
CPU. La patilla NMI está reservada para eventos drásticos como pueden ser una falla en
la fuente de poder o algún error de paridad en la memoria. Su nombre, externa, que es
una interrupción no enmascarable; es decir, que no se puede deshabilitar.

En lugar de ser enviadas directamente a la CPU, las interrupciones generadas por


eventos externos se canalizan a través de un circuito integrado llamado “PIC 8259A” (las
siglas corresponden a Programmable Interrupt Controller: controlador programable de
interrupciones). El PIC es controlado por la CPU mediante una serie de puertos, e
interrumpe a ésta por medio de la patilla INTR. También permite habilitar y deshabilitar
interrupciones emitidas por otros dispositivos.

Las interrupciones que utilizan la patilla INTR pueden controlarse mediante dos
instrucciones de la CPU llamadas Sti (set interrupt) y Cli (clear interrupt). La asignación de
dispositivos a niveles específicos de interrupción es realizada por el fabricante. Estas
asignaciones son físicas y no pueden alterarse mediante el software.

No es posible desactivar a las interrupciones externas.

M. D. O. H. Sonia Alvarado Mares


55
Lenguaje Ensamblador

1.3.2 Software.
Las interrupciones de software pueden ser activadas directamente por el ensamblador
invocando al número de interrupción deseada con la instrucción INT.

El uso de las interrupciones nos ayuda en la creación de programas, utilizándolas


nuestros programas son más cortos, es más fácil entenderlos y usualmente tienen un
mejor desempeño debido en gran parte a su menor tamaño.

Este tipo de interrupciones podemos separarlas en dos categorías: las interrupciones del
sistema operativo DOS y las interrupciones del BIOS.

La diferencia entre ambas es que las interrupciones del sistema operativo son más fáciles
de usar pero también son más lentas ya que estas interrupciones hacen uso del BIOS
para lograr su cometido, en cambio las interrupciones del BIOS son mucho más rápidas
pero tienen la desventaja que, como son parte del hardware son muy específicas y
pueden variar dependiendo incluso de la marca del fabricante del circuito.

La elección del tipo de interrupción a utilizar dependerá únicamente de las características


que le quiera dar a su programa: velocidad (utilizando las del BIOS) o portabilidad
(utilizando las del DOS).

El operando de una interrupción indica cuál es la rutina a activar. La dirección de la rutina


es localizada por medio de una tabla que el sistema mantiene a partir de la dirección
0000:0000h. Existen 256 entradas de 4 bytes de longitud, y cada interrupción proporciona
varias funciones. Las interrupciones de 00h a 1Fh corresponden al BIOS y de 20h a FFh
son del DOS y BASIC. El apéndice F proporciona una lista de las interrupciones para
equipo XT.

M. D. O. H. Sonia Alvarado Mares


56
Lenguaje Ensamblador

1.4 ESTRUCTURA DE UN PROGRAMA EN ENSAMBLADOR.


Existen ciertas normas para crear un programa en lenguaje ensamblador. La primera se
refiere al formato interno de cada instrucción del lenguaje. Toda línea de código debe
digitarse bajo ciertas reglas, las cuales pueden considerarse como la sintaxis propia del
lenguaje. Sin embargo, en la formación de instrucciones también entra en juego la
semántica. La segunda norma es el formato externo del programa, que puede equiparse
con una capa que rodeará al programa para ayudar a definir su entorno.

El formato interno.

El formato interno de una línea de código se puede resumir en cuatro partes. La etiqueta /
variable / constante (puede definirse o no, y si se define debe estar seguida por
separadores, ya sea uno o más espacios o tabuladores). El nombre nemónico / directiva,
que puede equiparse con el verbo o la acción por realizar, seguido de uno o más
separadores (espacios o tabuladores). El operando, que generalmente se divide en dos
(aunque existen instrucciones que sólo opera con uno): el destino (que será el depósito
del algún resultado) y la fuente de la información (el originador de la “acción”). El destino y
la fuente (si existe ésta) deben estar separados por una coma. Finalmente tenemos el
comentario, que siempre va precedido por el símbolo “;” (debe estar separado del
operando por uno o más espacios o tabuladores, y puede existir o no).

El formato externo.

El formato externo está formado por varios comandos clave que permiten establecer el
entorno operativo del programa. Entre ellos tenemos uno que define el modelo de
memoria (básicamente establece cuáles y cuántos segmentos se van a usar), los
diferentes segmentos que contendrá el código, los datos y la pila, así como el comienzo y
final del programa. Ahora bien, existen dos maneras de definir el programa: en la primera
se usan directivas simplificadas y en la segunda no se usan. Las directivas simplificadas
ayudan a esclarecer ciertos comandos crípticos del programa, permitiendo que sean más
legibles, y se incluyeron en las versiones del MASM 5.0 y posteriores.

Límites de los segmentos.

Como ya dijimos, un programa contiene cuatros segmentos, los cuales ala hora de
definirlos no necesariamente deben estar en un orden determinado. De hecho el

M. D. O. H. Sonia Alvarado Mares


57
Lenguaje Ensamblador

segmento extra (ES) no se define como parte del programa, solamente se hace referencia
a él en otro de los segmentos, regularmente en el segmento de código.

Un segmento inicia en un límite de párrafo, que es una dirección por lo común divisible
entre el 16 decimal, o el 10 hexadecimal. Suponga que un segmento de datos inicia en la
localidad de memoria 045F0H. Ya que en este y todos los demás casos el último dígito
hexadecimal de la derecha es cero, los diseñadores de computadoras decidieron que
sería innecesario almacenar el dígito cero en el registro del segmento. Así, 045F0H se
almacena como 045F, con el cero de la extrema derecha sobreentendido.

Desplazamiento de segmentos.

En un programa, todas las localidades de memoria están referidas a una dirección inicial
de segmento. La distancia en bytes desde la dirección del segmento se define como el
desplazamiento (offset). Un desplazamiento de dos bytes (16 bits) puede estar en el
rango de 0000H hasta FFFFH, o bien, desde cero hasta 65,535. Así, el primer byte del
segmento de código tiene un desplazamiento 00, el segundo byte tiene un
desplazamiento 01, etc., hasta el desplazamiento 65535. Para referir cualquier dirección
de memoria en un segmento, el procesador, el procesador combina la dirección del
segmento en un registro de segmento con un valor de desplazamiento.

En el ejemplo siguiente, el registro DS contiene la dirección de segmento del segmento de


datos en 045F0H y una instrucción hace referencia a una localidad con un
desplazamiento de 0032H bytes dentro del segmento de datos.

Por tanto, la localidad real de memoria del byte referido por la instrucción es 04622H:

Dirección del segmento DS 045F0H


Desplazamiento + 0032H
Dirección real 04622H

Note que un programa tiene uno o más segmentos, los cuales pueden iniciar casi en
cualquier lugar de memoria, variar en tamaño y estar en cualquier orden.

M. D. O. H. Sonia Alvarado Mares


58
Lenguaje Ensamblador

1.4.1 Data Segment.


El Propósito del segmento de datos en un programa .EXE es definir constantes, áreas de
trabajo y áreas de entrada/salida. El ensamblador permite la definición de elementos de
varias longitudes de acuerdo don el conjunto de directivas que defina datos. Por ejemplo,
DB define un byte y DW define una palabra. Un elemento de datos puede contener un
valor indefinido (esto es, no inicializado) o una constate, definida como una cadena de
caracteres o como un valor numérico. A continuación está el formato general para la
definición de datos:

[nombre] Dn expresión

Nombre. Un programa que hace referencia a un elemento de dato lo hace por medio de
un nombre. Por otro lado, el nombre de un elemento es opcional, indicado por los
corchetes. La sección anterior “Instrucciones”, proporciona las reglas para la formación de
los nombres.

Directivas (Dn). Las directivas que definen elementos de datos son DB (byte), DW
(palabra), DD (palabra doble), DF (palabra larga), DQ (palabra cuádruple) y DT (diez
bytes), cada una indica de manera explícita la longitud del elemento definido.

Expresión. La expresión es un operando que puede contener un signo de interrogación


para indicar un elemento no utilizado, como

VAR1 DB ? ; elemento no inicializado

En este caso, cuando su programa inicie la ejecución el valor inicial de VAR1 no es


conocido. En la práctica, lo normal antes de usar este elemento es mover algún valor a él
(lo que sea, pero debe ser apropiado al tamaño definido).

También puede utilizar el operando para definir una constante como

VAR2 DB 25 ; elemento inicializado

Puede usar con libertad este valor inicializado en su programa y aun puede cambiar el
contenido de VAR2.

Una expresión puede contener varios valores constantes separados por comas y limitados
sólo por la longitud de la línea, como sigue:

VAR3 DB 11, 12, 13, 14, 15, 16


M. D. O. H. Sonia Alvarado Mares
59
Lenguaje Ensamblador

El ensamblador define estas constantes en bytes contiguos. Una referencia a VAR3 es a


la primera constante de un byte, 11 (puede pensar en el primer byte como VAR3+0), y
una referencia a VAR3+1 es a la segunda constante, 12. Por ejemplo, la instrucción

MOV AL, VAR3+3

carga el valor 14 (0EH) en el registro AL. También la expresión permite duplicación de


constantes en un enunciado de la forma general

[nombre] Dn contador de repeticiones DUP (expresión) …

Los ejemplos siguientes ilustran la duplicación:

DW 10 DUP (?) ; Diez palabras, no inicializadas


DB 5 DUP (14) ; Cinco palabras con 0E0E0E0E0E hexadecimal
DB 3 DUP (4 DUP (8)) ; Doce 8

El tercer ejemplo genera cuatro copias del dígito 8 (8888) y duplica el valor tres veces,
produciendo un total de doce 8.

Una expresión puede definir e inicializar una cadena de caracteres o una constante
numérica.

Cadenas de caracteres.

Las cadenas de caracteres son usadas para datos descriptivos como nombres de
personas y títulos de páginas. La cadena está definida dentro de apóstrofos, como ´PC´, o
dentro de comillas, como “PC”. El ensamblador traduce las cadenas de caracteres en
código objeto en formato ASCII normal.

Extrañamente, DB es el único formato que define una cadena de caracteres que excede a
dos caracteres y los almacena en la secuencia normal de izquierda a derecha. En
consecuencia, DB es el formato convencional para la definición de datos de caracteres de
cualquier longitud. Un ejemplo es

DB ´Cadena de caracteres´

El ensamblador almacena los caracteres en formato ASCII, sin apóstrofos. Si la cadena


debe contener un apóstrofo o una comilla, usted puede definirlo en una de las formas
siguientes:

DB “Honest Ed´s PC Emporium” ; Comillas para la cadena, una comilla


para el apóstrofo
DB ´Honest Ed´ ´s PC Emporium´ ; Una comilla para la cadena, dos
Comillas seguidas para el apóstrofo

Constantes numéricas.

Las constantes numéricas son usadas para definir valores aritméticos y direcciones de
memoria. Las constantes no están definidas entre comillas, pero van seguidas por un
M. D. O. H. Sonia Alvarado Mares
60
Lenguaje Ensamblador

especificador de base opcional, tal como H en el valor hexadecimal 12H. Para la mayoría
de las directivas de definición de datos, el ensamblador convierte constantes numéricas
definidas a hexadecimal y almacena los bytes generados en código objeto en orden
inverso –de derecha a izquierda. A continuación están los diferentes formatos nuericos.

Decimal.

El formato decimal permite definir con los dígitos decimales 0 a 9, seguidos de manera
opcional por el especificador de base D, tal como 125 o 125D. Aunque el ensamblador
permite que usted defina valores en formato decimal, como una conveniencia al codificar,
él convierte sus valores decimales a código objeto binario y los representa en
hexadecimal. Por ejemplo, una definición del decimal 125 se convirtió en 7D hexadecimal.

Hexadecimal.

El formato hexadecimal permite definir con los dígitos hexadecimales de 0 a F, seguidos


por especificador de base H, que se puede usar para definir valores binarios. Ya que el
ensamblador espera que una referencia que empiece con una letra es un nombre
simbólico, el primer dígito de una constante hexadecimal debe ser de 0 a 9. Ejemplos son
2EH y 0FD8H, que el ensamblador almacena como 2E y D80F, respectivamente. Note
que los bytes en el segundo ejemplo son almacenados en orden inverso.

Binario.

El formato binario permite definir con los dígitos binarios 0 y 1, seguidos por el
especificador de base B. El uso normal del formato binario es para distinguir valores en
las instrucciones de manejo de bits AND, OR, XOR y TEST.

Ya que el ensamblador convierte todos los valores numéricos a binarios ( y los representa
en hexadecimal), las definiciones de 12, C hex y 1100 binario general el mismo valor :
0000 1100 binario o 0C hex, dependiendo de cómo vea el contenido del byte.

Cómo las letras D y B actúan tanto como especificadotes de base como dígitos
hexadecimales, pueden causar alguna confusión. Como solución, MASM 6.0 introdujo el
uso de la T (por ten, diez) y la Y (por binary, binario) como especificadores de base para
decimal y binario, respectivamente.

Real.

El ensamblador convierte un valor de real dato –una constante decimal o hexadecimal


seguidas por el especificador de base R- en formato de punto flotante para uso con un
coprocesador matemático.

Asegúrese de distinguir entre el uso de las constantes numéricas y de caracteres. Una


constante de carácter definida como DB

Identificadores.

M. D. O. H. Sonia Alvarado Mares


61
Lenguaje Ensamblador

Un identificador es un nombre que se aplica a elementos en el programa. Los dos tipos de


identificadores son: nombre, que se refiere a la dirección de un elemento de datos, y
etiqueta, que se refiere a la dirección de una instrucción. Las mismas reglas se aplican
tanto para los nombres como para las etiquetas. Un identificador puede utilizar los
siguientes caracteres:

Letra del alfabeto desde la A hasta la Z


Dígitos desde el 0 hasta 9 (no puede ser el primer carácter)

Caracteres especiales signo de interrogación (?)


subrayado (_)
signo de pesos ($)
arroba (@)
punto (.) (no puede ser el primer carácter).

El primer carácter de un identificador debe ser una letra o un carácter especial, excepto el
punto. Ya que el ensamblador utiliza algunos símbolos especiales en palabras que inician
con el símbolo @, debe evitar usarlo en sus definiciones.

El ensamblador trata las letras mayúsculas y minúsculas como iguales. La longitud


máxima de un identificador es de 31 caracteres (247 desde el MASM 6.0). Ejemplos de
nombres válidos son COUNT, PAGE25 y $E10. Se recomienda que los nombres sean
descriptivos y con significado. Los nombres de registros, como AX, DI y AL, están
reservados para hacer referencia a esos mismos registros. En consecuencia, en una
instrucción tal como:

ADD AX, BX

el ensamblador sabe de forma automática que AX y BX se refieren a los registros. Sin


embargo, en una instrucción como:

MOV REGSAVE, AX

el ensamblador puede reconocer el nombre REGSAVE sólo si se define en algún lugar del
programa.

M. D. O. H. Sonia Alvarado Mares


62
Lenguaje Ensamblador

1.4.2 Stack Segment.

Los programas .COM y .EXE, requieren un área del programa reservada como una pila
(stack). El propósito de la pila es mantener un espacio para el almacenamiento temporal
de direcciones y datos.

El DOS define de manera automática la pila para un programa .COM, mientras que para
un programa .EXE usted debe definir en forma explícita la pila. Cada elemento de dato en
la pila es una palabra (dos bytes). El registro SS, como es inicializado por el DOS,
contiene la dirección del inicio de la pila. Inicialmente, el SP contiene el tamaño de la pila,
un valor que apunta al byte que está pasando el final de la pila. La pila difiere de otros
segmentos en su método de almacenar los datos: empieza en la localidad más alta y
almacena los datos hacia abajo por la memoria.

La instrucción PUSH (entre otras) disminuye el SP en 2 hacia abajo, hacia la siguiente


palabra almacenada de la pila y coloca (o empuja, push) un valor ahí. La instrucción POP
(entre otras) regresa el valor de la pila e incrementa el SP en 2 hacia arriba, hacia la
siguiente palabra almacenada.

Note que las instrucciones POP son codificadas en secuencia inversa a la instrucción
PUSH. Así el ejemplo

Ejemplo de operación sobre la pila (todos los datos son arbitrarios):

M. D. O. H. Sonia Alvarado Mares


63
Lenguaje Ensamblador

1.4.3 Code Segment.

El segmento de código (CS) contiene las instrucciones de máquina que son ejecutadas.
Por lo común, la primera instrucción ejecutable está en el inicio del segmento, y el sistema
operativo enlaza a esa localidad para iniciar la ejecución del programa. Como su nombre
indica, el registro del CS direcciona el segmento de código. Si su área de código requiere
más de 64 K, su programa puede necesitar definir más de un segmento de código.

Palabras reservadas.

Ciertas palabras en lenguaje ensamblador están reservadas para sus propósitos propios,
y son usadas sólo bajo condiciones especiales. Por categorías las palabras reservadas
incluyen

• instrucciones, como MOV y ADD, que son operaciones que la computadora puede
ejecutar;
• directivas, como END o SEGMENT, que se emplean para proporcionar comandos
al ensamblador;
• operadores, como FAR y SIZE, que se utilizan en expresiones; y
• símbolos predefinidos, como @Data y @Model, que regresan información a su
programa.

El uso de una palabra reservada para un propósito equivocado provoca que el


ensamblador genere un mensaje de error.

M. D. O. H. Sonia Alvarado Mares


64
Lenguaje Ensamblador

1.4.4 Instrucciones del programa.


Un programa fuente en ensamblador contiene dos tipos de sentencias: las instrucciones
y las directivas. Las instrucciones se aplican en tiempo de ejecución, pero las directivas
sólo son utilizadas durante el ensamblaje. El formato de una sentencia de instrucción es el
siguiente:

[etiqueta:] nombre_instrucción [operandos] [;comentario]

Los corchetes, como es normal al explicar instrucciones en informática, indican que lo


especificado entre ellos es opcional, dependiendo de la situación que se trate.

Campo etiqueta. Es el nombre simbólico de la primera posición de una instrucción,


puntero o dato. Consta de hasta 31 caracteres que pueden ser las letras de la A a la Z, los
números del 0 al 9 y algunos caracteres especiales como «@», «_», «.» y «$». Reglas:

• Si se utiliza el punto «.» éste debe colocarse como primer carácter de la etiqueta.

• El primer carácter no puede ser un dígito.

• No se pueden utilizar los nombres de instrucciones o registros como nombres de


etiquetas.

Las etiquetas son de tipo NEAR cuando el campo de etiqueta finaliza con dos puntos (:);
esto es, se considera cercana: quiere esto decir que cuando realizamos una llamada
sobre dicha etiqueta el ensamblador considera que está dentro del mismo segmento de
código (llamadas intrasegmento) y el procesador sólo carga el puntero de instrucciones
IP. Téngase en cuenta que hablamos de instrucciones; las etiquetas empleadas antes de
las directivas, como las directivas de definición de datos por ejemplo, no llevan los dos
puntos y sin embargo son cercanas.

Las etiquetas son de tipo FAR si el campo de etiqueta no termina con los dos puntos: en
estas etiquetas la instrucción a la que apunta no se encuentra en el mismo segmento de
código sino en otro. Cuando es referenciada en una transferencia de control se carga el
puntero de instrucciones IP y el segmento de código CS (llamadas intersegmento).

Campo nombre_instrucción. Contiene el mnemónico de las instrucciones, o bien una


directiva de las que veremos más adelante.

M. D. O. H. Sonia Alvarado Mares


65
Lenguaje Ensamblador

Campo operandos. Indica cuales son los datos implicados en la operación. Puede haber
0, 1 ó 2; en el caso de que sean dos al 1º se le llama destino y al 2º -separado por una
coma- fuente.
mov ax, es:[di] --> ax destino
es:[di] origen

Campo comentarios. Cuando en una línea hay un punto y coma (;) todo lo que sigue en
la línea es un comentario que realiza aclaraciones sobre lo que se está haciendo en ese
programa, resulta de gran utilidad de cara a realizar futuras modificaciones al mismo.

1.4.5 Directivas.
El MASM posee un conjunto de instrucciones que no pertenecen al lenguaje
ensamblador propiamente sino que son instrucciones que únicamente son reconocidas
por el ensamblador y que han sido agregadas para facilitar la tarea de ensamblado, tanto
para el programador como para el programa que lo lleva a cabo. Dichas instrucciones son
denominadas directivas. En general, las directivas son usadas para especificar la
organización de memoria, realizar ensamblado condicional, definir macros, entrada,
salida, control de archivos, listados, cross-reference, direcciones e información acerca de
la estructura de un programa y las declaraciones de datos. El apéndice D proporciona
una lista completa de estas directivas.

Conjunto de instrucciones.-
instrucciones Dentro de las directivas más importantes, tenemos las que
establecen el conjunto de instrucciones a soportar para un microprocesador en especial:

.8086(defecto).- Activa las instrucciones para el 8086 y 8088 e inhibe las del 80186 y
80286.
.8087(defecto).- Activa instrucciones para el 8087 y desactiva las del 80287.
.186.- Activa las instrucciones del 80186.
.286c.- Activa instrucciones del 80286 en modo no protegido.
.286p.- Activa instrucciones del 80286 en modo protegido y no protegido.
.287.- Activa las instrucciones para el 80287.

Declaración de segmentos.-
segmentos En lo que respecta a la estructura del programa tenemos
las directivas SEGMENT y ENDS que marcan el inicio y final de un segmento del
programa. Un segmento de programa es una colección de instrucciones y/o datos cuyas
direcciones son todas relativas para el mismo registro de segmento. Su sintaxis es:

nombre SEGMENT [alineación] [combinación] [´clase´]


nombre ENDS

El nombre del segmento es dado por nombre, y debe ser único. Segmentos con el mismo
nombre se tratan como un mismo segmento. Las opciones alineación, combinación, y
clase proporcionan información al LINK sobre cómo ajustar los segmentos. Para
alineación tenemos los siguientes valores: byte (usa cualquier byte de dirección), word
(usa cualquier palabra de dirección, 2 bytes/word), para (usa direcciones de párrafos, 16
bytes/párrafo, deafult), y page (usa direcciones de página, 256 bytes/page). combinación
define cómo se combinarán los segmentos con el mismo nombre. Puede asumir valores

M. D. O. H. Sonia Alvarado Mares


66
Lenguaje Ensamblador

de: public (concatena todos los segmentos en uno solo), stack (igual al anterior, pero con
direcciones relativas al registro SS, common (crea segmentos sobrepuestos colocando el
inicio de todos en una misma dirección), memory (indica al LINK tratar los segmentos
igual que MASM con public, at address (direccionamiento relativo a address). clase
indica el tipo de segmento, señalados con cualquier nombre. Cabe señalar que en la
definición está permitido el anidar segmentos, pero no se permite de ninguna manera el
sobreponerlos.

Fin de código fuente.-


fuente Otra directiva importante es la que indica el final de un módulo. Al
alcanzarla el ensamblador ignorará cualquier otra declaración que siga a ésta. Su sintaxis
es:

END [expresión]

la opción expresión permite definir la dirección en la cual el programa iniciará.

Asignación de segmentos.-
segmentos La directiva ASSUME permite indicar cuales serán los
valores por defecto que asumirán los registros de segmento. Existen dos formas de hacer
esto:

ASSUME registrosegmento:nombre,,,
ASSUME NOTHING

NOTHING cancela valores previos.

Etiquetas.-
Etiquetas. Las etiquetas son declaradas

nombre:

donde nombre constituye una cadena de caracteres.

Declaración de datos.-
datos.- Estos se declaran según el tipo, mediante la regla

[nombre] directiva valor,,,

donde directiva puede ser DB (bytes), DW (palabras), DD (palabra doble), DQ (palabra


cuádruple), DT (diez bytes). También pueden usarse las directivas LABEL (crea etiquetas
de instrucciones o datos), EQU (crea símbolos de igualdad) , y el símbolo = ( asigna
absolutos) para declarar símbolos. Estos tienen la siguiente sintaxis:

nombre = expresión
nombre EQU expresión
nombre LABEL tipo

donde tipo puede ser BYTE, WORD, DWORD, QWORD, TBYTE, NEAR, FAR.

Declaración de estructuras.-
estructuras Para la declaración de estructuras de datos se emplea la
directiva STRUC. Su sintaxis es:

M. D. O. H. Sonia Alvarado Mares


67
Lenguaje Ensamblador

nombre STRUC
campos
nombre ENDS

1.5 PROCEDIMIENTO DE ENSAMBLE, ENLACE Y EJECUCIÓN.

Antes de que sea posible formalizar la relación con el lenguaje ensamblador, es


indispensable conocer un poco más el ambiente que lo rodea. Este ambiente forma un
círculo que comprende varios procesos tales como crear el archivo fuente, ensamblarlo
(crear el archivo objeto), enlazarlo (crear el archivo ejecutable) y corregirlo o depurarlo.
Cada proceso es independiente de los otros, pero es necesario para la generación de un
programa ejecutable sin errores. Es decir, una vez creado el programa fuente se pasa al
proceso de enlace, y este proceso genera a su vez el programa ejecutable.

Será usted muy afortunado si su programa actúa sin errores la primera vez; la mayoría de
los programas requieren una cuarta etapa que consiste en corregir y depurar los errores.

La programación, en cualquier lenguaje que sea, necesita al menos de tres herramientas:


un editor de texto para crear el archivo fuente, un compilador para convertirlo en archivo
objeto y un enlazador (linker) para generar finalmente el programa ejecutable. Una cuarta
herramienta sería el depurador (debugger), aunque más bien sirve de soporte para
verificar, depurar y en caso necesario corregir el programa ejecutable. La programación
en ensamblador no es la excepción, y también necesita las herramientas anteriores.

EDICIÓN.
EDICIÓN.

Los archivos fuente de código ensamblador deben estar en formato ASCII standard. Se
puede usar cualquier editor de texto, el compilador (ensamblador) es el MASM y el
enlazador es el programa LINK. Al utilizar el editor de texto para crear un archivo, se esta
formando el archivo fuente (archivo que contiene todas las instrucciones en el formato del
ensamblador). La extensión usada en ensamblador para el archivo fuente es .ASM. Este
archivo es traducido por el MASM, generando así un archivo intermedio en formato OBJ.
El formato OBJ es conocido como formato intermedio porque aún no es ejecutable. El
enlazador (linker) combina uno o más archivos .OBJ para generar el archivo ejecutable,
cuya extensión es .EXE (también puede ser .COM, dependiendo de la forma en que se
ensambló).

Para esto puede usarse cualquier editor que permita crear archivos sin formato, por
ejemplo: Edlin, Edit, Write, El editor del Turbo Pascal, Works, Word, etcétera. Las
declaraciones pueden ser introducidas en mayúsculas y/o minúsculas. Una buena
práctica de programación es poner todas las palabras reservadas (directivas e

M. D. O. H. Sonia Alvarado Mares


68
Lenguaje Ensamblador

instrucciones) en mayúsculas y todo lo del usuario en minúsculas para fines de facilidad


de lectura del código.

ENSAMBLADO.

Una vez creado el archivo fuente, es necesario que pase por el MASM para generar el
archivo intermedio (formato OBJ). El comando para ello es:

MASM archivo;

seguido por la tecla [enter]. MASM es el nombre del macroensamblador, archivo es el


nombre del programa (sin extensión), y el signo ; le especifica a MASM que ensamble
directamente el programa.

He aquí un ejemplo:

MASM prueba;

Suponiendo que el nombre de su programa sea prueba. Si se omitiese el punto y como,


MASM respondería con lo siguiente:

Source filename [.ASM]: digite prueba


Object filename [prueba.obj]: [Enter]
Source listing [NUL.LST]: [Enter]
Cross-reference [NUL.CRF]: [Enter]

MASM pondrá entre corchetes la respuesta que considere correcta. La opción Source
listing (listado fuente) permite generar un archivo que contendrá línea por línea el código
de máquina (en notación hexadecimal) generado y la línea de su código fuente. También
contiene información adicional, por ejemplo los símbolos usados en el programa y los
diferentes segmentos. El nombre NUL.LST usado por MASM indica que usted no desea
dicho listado. La opción Cross-reference (referencias recíprocas) contiene información
sobre cada símbolo de su código fuente, mostrando el número de línea donde fue
declarado y todas las líneas que hacen referencia a él. De nuevo, el nombre NUL.CRF
indica que tampoco desea generar dicho listado.

MASM ofrece la opción de recibir parámetros desde la línea para comandos de MS-DOS.
Existen demasiados parámetros, los que se mencionan más adelante son sólo algunos
de ellos; sin embargo, es conveniente explicar cómo se pasan al MASM. Todo parámetro
pasado al MASM debe estar precedido por el símbolo “/”, seguido de la inicial del
parámetro (pueden repetirse uno o más parámetros en la línea para comandos. Una vez
especificados todos los parámetros, se incluye el nombre del archivo por ensamblar.

Los parámetros pueden ser:

/A escribe los segmentos en orden alfabético


/S escribe los segmentos en orden del fuente
/B num fija buffer de tamaño num
/C especifica un archivo de referencias cruzadas

M. D. O. H. Sonia Alvarado Mares


69
Lenguaje Ensamblador

/L especifica un listado de ensamble


/D crea listado del paso 1
/D sym define un símbolo que puede usarse en el ensamble
/I path fija path para buscar archivos a incluir
/ML mantiene sensitividad de letras (mayús./minús) en nombres
/MX mantiene sensitividad en nombre públicos y externos
/MU convierte nombres a mayúsculas
/N suprime tablas en listados
/P checa por código impuro
/R crea código para instrucciones de punto flotante
/E crea código para emular instrucciones de punto flotante
/T suprime mensajes de ensamble exitoso
/V despliega estadísticas adicionales en pantalla
/X incluir condicionales falsos en pantalla
/Z despliega líneas de error en pantalla

La línea MASM /v /z prueba; le indica al ensamblador que ensamble el programa llamado


prueba, que despliega al final el número de líneas fuente y los símbolos procesados (/v), y
que sí existe algún error despliegue la línea donde ocurrió (/z). En ocasiones son
demasiados los parámetros que deseamos pasarle al MASM, y sería sumamente tedioso
y engorroso digitar todo de nuevo cada vez que se ensambla el programa. Además,
existe un límite a la cantidad de caracteres que puede digitarse en la línea para
comandos (128, lo cual es una restricción de MS-DOS).

La otra forma de invocar al ensamblador es sólo tecleando MASM y respondiendo a la


información que se solicita. Para omitir algún valor sólo basta teclear ENTER si dar
ningún valor.

El MASM traduce (ensambla) el archivo de código fuente a otro de formato .OBJ. Sin
embargo, MS-DOS no puede ejecutar este último archivo. Primero es necesario pasar el
archivo .OBJ por otro proceso que definirá muchos detalles y generará el archivo
ejecutable; dicho proceso es realizado por el Enlazador. El comando para invocar al
Enlazador tiene similitud con el que se usa para invocar al MASM. Simplemente digite:

LINK archivo + (otros archivos .OBJ o bibliotecas);

Por ejemplo, el comando LINK prueba; generará el archivo prueba.EXE.

Para ampliar el concepto anterior, suponga que tiene dos archivos con extensión .OBJ:
prueba1.obj y prueba2.obj, y que además desea mezclar los dos archivos anteriores con
una biblioteca de gráfico llamada bibliogr.lib. Usando el enlazador para generar el
programa ejecutable, se utilizaría el siguiente comando:

LINK prueba1 + prueba2 + bibliogr;

Tome en cuenta que en la línea para comandos, el primer archivo siempre debe ser el
principal, es decir, el que controlará la secuencia de eventos. El objetivo de enlazar todos
los archivos .OBJ es poder generar un solo archivo ejecutable con la extensión .EXE. En
el ejemplo anterior se generaría el archivo PRUEBA1.EXE.

Los parámetros que este requiere son:

M. D. O. H. Sonia Alvarado Mares


70
Lenguaje Ensamblador

LINK objeto [,[ejecutable][,[mapa][,[librería]]]]][opciones][;]

donde:
objeto.- Es el nombre para el archivo .OBJ
ejecutable.- Nombre del archivo .EXE
mapa.- Nombre del archivo mapa
librería.- Nombre del archivo biblioteca de rutinas
opciones.- Pueden ser:

/HELP muestra lista de opciones


/PAUSE pausa en el proceso
/EXEPACK empaca archivo ejecutable
/MAP crea mapa se símbolos públicos
/LINENUMBERS copia número de líneas al mapa
/NOIGNORECASE mantiene sensitividad en nombres
/NODEFAULTLIBRARYSEARCH no usa bibliotecas por defecto
/STACK: fija el tamaño del stack a usar
/CPARMAXALLOC: número fija alojación máxima de espacio
/HIGH fija la dirección de carga más alta
/DSALLOCATE aloja grupo de datos
/NOGROUPASSOCIATION ignora asociaciones para direcciones
/OVERLAYINTERRUPT:número asigna nuevo número a la INT 03Fh
/SEGMENTS:número procesa un número de segmentos
/DOSSEG sigue la convención de orden de DOS

EJECUCIÓN.
EJECUCIÓN.

En el entorno MS-DOS existen dos tipos diferentes de programas ejecutables desde la


línea para comandos: los que tienen la extensión .COM y los que tienen la extensión
.EXE. Las diferencias entre uno y otro se delinearán más adelante. Sin embargo, ambos
tienen algo en común: hacen uso de una estructura en memoria llamada PSP.

El Prefijo del Segmento de Programa (PSP).

El PSP (Programa Segment Prefix) es una estructura usada para controlar ciertos
aspectos del programa. Tiene una longitud de 256 bytes, y siempre está ubicado en los
primeros 256 bytes del segmento donde se carga el programa (forma parte del programa
en la memoria). En esta estructura se almacena información importante, por ejemplo la
tabla de entorno (Dónde se guarda la información sobre las variables de entorno).

Para la ejecución del programa simplemente basta teclear su nombre en el prompt de MS-
DOS y teclear ENTER. Con esto el programa será cargado en memoria y el sistema
procederá a ejecutarlo. El proceso completo para poder crear un programa ejecutable
con el Microsoft Macro Assembler se muestra abajo.

M. D. O. H. Sonia Alvarado Mares


71
Lenguaje Ensamblador

y lo que se vería en pantalla sería lo siguiente:

C:\DATA\PROGRAMS\ASM>masm main
Microsoft (R) Macro Assembler Version 4.00
Copyright (C) Microsoft Corp 1981, 1983, 1984, 1985. All rights reserved.

Object filename [main.OBJ]:


Source listing [NUL.LST]:
Cross-reference [NUL.CRF]:

50966 Bytes symbol space free

0 Warning Errors
0 Severe Errors

C:\DATA\PROGRAMS\ASM>masm task
Microsoft (R) Macro Assembler Version 4.00
Copyright (C) Microsoft Corp 1981, 1983, 1984, 1985. All rights reserved.

Object filename [task.OBJ]:


Source listing [NUL.LST]:
Cross-reference [NUL.CRF]:

51034 Bytes symbol space free

0 Warning Errors
0 Severe Errors

C:\DATA\PROGRAMS\ASM>link main+task

Microsoft (R) 8086 Object Linker Version 3.05


Copyright (C) Microsoft Corp 1983, 1984, 1985. All rights reserved.

Run File [MAIN.EXE]:


List File [NUL.MAP]:
Libraries [.LIB]:

C:\DATA\PROGRAMS\ASM>main

M. D. O. H. Sonia Alvarado Mares


72
Lenguaje Ensamblador

Entrando a un submodulo....
.......saliendo del submodulo.

C:\DATA\PROGRAMS\ASM>

DEPURACIÓN.
DEPURACIÓN.

Para la depuración de un programa en ensamblador tenemos disponibles dos


herramientas. Por un lado tenemos el debugger que nos proporciona MS-DOS
(DEBUG.EXE) y por otro lado tenemos el que nos proporciona Microsoft (SYMDEB.EXE).
Este último trabaja igual que el de MS-DOS pero nos proporciona muchas ventajas más.

Una de ellas es la facilidad de desplegar el código fuente correspondiente a la instrucción


que se esta ejecutando (si el programa ejecutable fue ensamblado o compilado con un
ensamblador o compilador compatible), nos permite ejecutar comandos del S.O. y nos
permite obtener información de las interrupciones de manera simbólica.

LA UTILERIA EXE2BIN Y LOS ARCHIVOS .EXE Y .COM.

Para MS-DOS sólo existen dos tipo de archivos ejecutables los .COM y .EXE. Ambos
archivos difieren en algunas cosas. Primero, las ventajas de los .EXE son dobles, nos
permiten tener archivos reubicables y el uso de hasta cuatro segmentos (STACK, DATA,
EXTRA y CODE) de hasta 64KB cada uno. Un archivo .COM sólo puede tener un
segmento de 64KB, en el que se tiene tanto código como pila, y datos. La desventaja de
los .EXE es que agrega n 512 bytes como cabecera con información para la reubicación
del código. Un .COM no es reubicable, siempre inicia en la dirección 0100H.

Si nuestro programa no es muy grande 64KB son más que suficientes. Por lo que
conviene crearlo como .COM, para esto se cuenta con la utilería EXE2BIN.EXE que nos
proporciona el sistema operativo. y que nos permite crear .COM a partir de .EXE . Las
restricciones para esto son las siguientes: el archivo a convertir no debe estar empacado,
no debe tener segmento de stack, debe tener sólo segmento de código y su tamaño debe
ser menor a 64KB.

EL LENGUAJE DE MÁQUINA.
MÁQUINA.

Lo que se conoce como lenguaje o código de máquina es el conjunto de códigos


numéricos (comúnmente expresados en hexadecimal) para cada una de las instrucciones
que el microprocesador es capaz de reconoce y ejecutar. Aun cuando finalmente es con
esta serie de números con los que el microprocesador trabaja, es muy difícil prrogramar a
este nivel. El lenguaje ensamblador fue desarrollado para liberar al programador de la
difícil tarea de tener que recordar todos los códigos y de las tediosas labores de cálculo
de localidades de memoria. Los códigos mnemónicos del ensamblador son una
substitución de los códigos numéricos mejor que en una relación 1:1. Por ejemplo, resulta
que mientras que tenemos de manera general un mnemónico para cargar un registro con
un valor (MOV) internamente, para cada una de las modalidades de direccionamiento o
registro afectado existe un código numérico.

M. D. O. H. Sonia Alvarado Mares


73
Lenguaje Ensamblador

La programación del computador en lenguaje de máquina, tanto la introducción de los


programas, su ejecución y su depuración es posible usando alguna utilería provista por el
sistema operativo y cabe mencionar que casi todos los sistemas operativos proveen al
usuario con estas facilidades. DOS no es la excepción; éste provee al usuario de la
utilería DEBUG. La siguiente sección da más información al respecto.

CREACIÓN Y DEPURACIÓN DE PROGRAMAS CON LA UTILERÍA


UTILERÍA DEBUG.

El la utilería de MS-DOS DEBUG es una herramienta muy poderosa que es desconocida


por muchos. Este provee una interfaz desde la cual es seguro no sólo explorar el
contenido de la memoria del computador y de los registros del microprocesador sino que
además provee los medios para la introducción de programas y su depuración, tanto en
ensamblador como en lenguaje de máquina. La utilización de esta herramienta se
ejemplifica con el siguiente ejemplo.

1. Desde el prompt del sistema invoque la utilería.

C:\> debug

2. En el prompt de la utilería introducir el siguiente programa en código de máquina.

-e 100 BA 40 00 8E DA BB 72 00 C7 07 34 12 EA 00 00 FF FF

3. Guardar el programa en un archivo.

-rcx
:11
-n reset.com
-w
-q

4. El paso anterior creará un archivo en el directorio vigente con el nombre


RESET.COM. La extensión .COM es importante, el nombre pudo ser cualquiera.
Este programa llama a las rutinas de inicialización del sistema, al ejecutarlo
veremos que el computador se reinicializa, o si estamos trabajando en una
ventana de DOS bajo Windnows esta se cerrará.

C:\> reset.com

Haga la prueba creando un programa más grande, esta vez introduciéndolo a través de
dos líneas de programa. Para guardarlo indique la cantidad de 1C bytes al invocar el
comando rcx del debug y sálvelo con extensión .COM.

-e 100 1E 31 C0 50 BA 0C 01 B4 09 CD 21 C3 48 6F 6C 61 20 6D 75 6E 64 6F

-e 116 21 21 21 0D 0A 24

M. D. O. H. Sonia Alvarado Mares


74
Lenguaje Ensamblador

1.6 ENTORNO DE PROGRAMACIÓN.


Existen varios ensambladores disponibles para ambiente MS-DOS: el IBM Macro
Assembler, el Turbo Assembler de Borland, el Turbo Editassm de Speedware, por citar
algunos. Una breve descripción de cada uno se propociona a continuación.

Macro Ensamblador IBM.- Está integrado por un ensamblador y un macroensamblador.


En gran medida su funcionamiento y forma de invocarlo es sumamente similar al de
Microsoft. Su forma de uso consiste en generar un archivo fuente en código ASCII, se
procede a generar un programa objeto que es ligado y se genera un programa .EXE.
Opcionalmente puede recurrirse a la utilería EXE2BIN de MS-DOS para transformarlo
a .COM. Es capaz de generar un listado con información del proceso de ensamble y
referencias cruzadas.

Macro Ensamblador de Microsoft.- Dependiendo de la versión, este ensamblador es


capaz de soportar el juego de instrucciones de distintos tipos de microprocesadores Intel
de la serie 80xx/80x86. En su versión 4.0 este soporta desde el 8086 al 80286 y los
coprocesadores 8087 y 80287. Requiere 128KB de memoria y sistema operativo MS-DOS
v2.0 o superior. Trabaja con un archivo de código fuente creado a partir de un editor y
grabado en formato ASCII. Este archivo es usado para el proceso de ensamble y
generación de código objeto. Posteriormente, y con un ligador, es creado el código
ejecutable en formato .EXE.

Turbo Editassm.- Este es desarrollado por Speddware, Inc., y consiste de un ambiente


integrado que incluye un editor y utilerías para el proceso de ensamble y depuración. Es
capaz de realizar el ensamble línea a línea, conforme se introducen los mnemónicos, y
permite revisar listas de referencias cruzadas y contenido de los registros. Este
ensamblador trabaja con tablas en memoria, por lo que la generación del código
ejecutable no implica la invocación explícita del ligador por parte del programador.
Adicionalmente permite la generación de listados de mensajes e información de cada
etapa del proceso y la capacidad de creación de archivos de código objeto.

Turbo Assembler.- De Borland Intl., es muy superior al Turbo Editassm. Trabaja de la


misma forma, pero proporciona una interfaz mucho más fácil de usar y un mayor conjunto
de utilerías y servicios.

M. D. O. H. Sonia Alvarado Mares


75
Lenguaje Ensamblador

En lo que se refiere a las presentes notas, nos enfocaremos al Microsoft Macro Assembler
v4.0. Los programas ejemplo han sido desarrollados con éste y está garantizado su
funcionamiento. Estos mismo programas posiblemente funcionen con otros
ensambladores sin cambios o con cambios mínimos cuando utilizan directivas o
pseudoinstrucciones.

Realmente la diferencia entre los ensambladores radica en la forma de generar el código


y en las directivas con que cuente, aunque estas diferencias son mínimas. El código
ensamblador no cambia puesto que los microprocesadores con los que se va a trabajar
son comunes. Así, todos los programas que se creen con un ensamblador en particular
podrán ser ensamblados en otro, cambiando las pseudo-operaciones no reconocidas por
el equivalente indicado en el manual de referencia del paquete empleado.

Los programas que componen el Macro Ensamblador Microsoft v4.0 son los siguientes:

Programa Descripción _________


MASM.EXE Microsoft Macro Assembler
LINK.EXE Microsoft 8086 object linker
SYMDEB.EXE Microsoft Symbolic Debuger Utility
MAPSYM.EXE Microsoft Symbol File Generator
CREF.EXE Microsoft Cross-Reference Utility
LIB.EXE Microsoft Library Manager
MAKE.EXE Microsoft Program Maintenance Utility
EXEPACK.EXE Microsoft EXE File Compression Utility
EXEMOD.EXE Microsoft EXE File Header Utility
COUNT.ASM Sample source file for SYMDEB session
README.DOC Updated information obtained after the manual
was printed.

El Microsoft Macro Assembler v4.0 crea código ejecutable para procesadores 8086,
8088, 80186, 80188, 80286, 8087 y 80287. Además es capaz de aprovechar las
instrucciones del 80286 en la creación de código protegido y no protegido.

El término macroensamblador es usado para indicar que el ensamblador en cuestión tiene


la capacidad de poder ensamblar programas con facilidad de macro. Una macro es una
pseudo-instrucción que define un conjunto de instrucciones asociadas a un nombre
simbólico. Por cada ocurrencia en el código de esta macro, el ensamblador se encarga de
substituir esa llamada por todas las instrucciones asociadas y, en caso de existir, se
dejan los parámetros con los que se estaba llamando la macro y no con los que había
sido definida. Es importante señalar que no se deja una llamada, como a una subrutina o
procedimiento, sino que se incorporan todas las instrucciones que definen a la macro.

M. D. O. H. Sonia Alvarado Mares


76
Lenguaje Ensamblador

M. D. O. H. Sonia Alvarado Mares


77

You might also like