Lenguaje Ensamblador - fcqi.tij.uabc.mxfcqi.tij.uabc.mx/usuarios/jjesuslg/apleu1.pdf · que se...

26
Lenguaje Ensamblador Apuntes de clase Facultad de Ciencias Químicas e Ingeniería Universidad Autónoma de Baja California – Campus Tijuana Prof. Juan Jesús López García Un agradecimiento especial a: - Anne Boutrell? estudiante -de intercambio- de la carrera de ingeniería en automatización y control, por la transcripción del texto. - David Villa Márquez, estudiante de ing. en electrónica por la revisión del texto y la realización de esquemas. Introducción Se conoce como Lenguaje Ensamblador al conjunto de instrucciones que una unidad de procesamiento puede realizar. Las actuales unidades de procesamiento se incluyen en un solo circuito integrado, conocido como microprocesador (μP); cada instrucción que ejecuta la unidad de procesamiento es en realidad un conjunto de instrucciones más simples incluidas en el hardware del mismo circuito (firmware), el conjunto de dichas instrucciones simples es conocido como microprogramación ya que se encuentran incluidas en el microprocesador. En 1978, la compañía XXX fabricante de calculadoras solicitó a la compañía Intel -fabricante de semiconductores- la construcción de un circuito integrado capaz de ejecutar un conjunto de instrucciones que le permitiría reducir la cantidad de circuitos, permitiéndole la reducción del tamaño y costo en la fabricación de calculadoras, en respuesta, Intel desarrolló el primer circuito μP al que nombró 4004 (poseía un canal de datos de 4 bits), un juego de NNN instrucciones (suma, resta, comparación...), registros de ¿?? bits y capacidad para direccionar YYY KB de memoria. Otros fabricantes de aparatos electrónicos (calculadoras, juguetes, ...) se interesaron por el circuito y su venta ascendió exponencialmente, fue entonces que Intel notó la importancia del desarrollo e invirtió esfuerzo en la fabricación de un μP mejorado, en 1980 saca al mercado el μP 8008 (canal de datos de 8 bits), tenía un juego de NNN instrucciones, registros de 16 bits y capacidad para direccionar 65,536 bloques diferentes de memoria (64 KB). A la par, la compañía Motorola -fabricante también de semiconductores- desarrolla el μP 6800 similar en capacidad al 8008 de Intel. Empieza entonces la competencia entre ambas compañías para ganar el mercado de venta de μP, produciendo las mejoras, casi a la par, en sus microprocesadores. La siguiente versión de Intel poseía mismo juego de instrucciones, velocidad de procesamiento similar, pero a diferencia del 8008, era capaz de direccionar hasta 1,048,576 bloques de memoria (1MB), Intel lo nombró μP 8088. La forma en que Intel aumentó su capacidad de direccionar memoria fue manipulando dos de sus registros de 16 bits para seleccionar localidades de 20 bits, para ello ideó un sistema lógico-físico de direccionamiento.

Transcript of Lenguaje Ensamblador - fcqi.tij.uabc.mxfcqi.tij.uabc.mx/usuarios/jjesuslg/apleu1.pdf · que se...

Lenguaje Ensamblador

Apuntes de clase

Facultad de Ciencias Químicas e Ingeniería Universidad Autónoma de Baja California – Campus Tijuana

Prof. Juan Jesús López García

Un agradecimiento especial a: - Anne Boutrell? estudiante -de intercambio- de la carrera de ingeniería en automatización y

control, por la transcripción del texto. - David Villa Márquez, estudiante de ing. en electrónica por la revisión del texto y la

realización de esquemas. Introducción Se conoce como Lenguaje Ensamblador al conjunto de instrucciones que una unidad de procesamiento puede realizar. Las actuales unidades de procesamiento se incluyen en un solo circuito integrado, conocido como microprocesador (µP); cada instrucción que ejecuta la unidad de procesamiento es en realidad un conjunto de instrucciones más simples incluidas en el hardware del mismo circuito (firmware), el conjunto de dichas instrucciones simples es conocido como microprogramación ya que se encuentran incluidas en el microprocesador. En 1978, la compañía XXX fabricante de calculadoras solicitó a la compañía Intel -fabricante de semiconductores- la construcción de un circuito integrado capaz de ejecutar un conjunto de instrucciones que le permitiría reducir la cantidad de circuitos, permitiéndole la reducción del tamaño y costo en la fabricación de calculadoras, en respuesta, Intel desarrolló el primer circuito µP al que nombró 4004 (poseía un canal de datos de 4 bits), un juego de NNN instrucciones (suma, resta, comparación...), registros de ¿?? bits y capacidad para direccionar YYY KB de memoria. Otros fabricantes de aparatos electrónicos (calculadoras, juguetes, ...) se interesaron por el circuito y su venta ascendió exponencialmente, fue entonces que Intel notó la importancia del desarrollo e invirtió esfuerzo en la fabricación de un µP mejorado, en 1980 saca al mercado el µP 8008 (canal de datos de 8 bits), tenía un juego de NNN instrucciones, registros de 16 bits y capacidad para direccionar 65,536 bloques diferentes de memoria (64 KB). A la par, la compañía Motorola -fabricante también de semiconductores- desarrolla el µP 6800 similar en capacidad al 8008 de Intel. Empieza entonces la competencia entre ambas compañías para ganar el mercado de venta de µP, produciendo las mejoras, casi a la par, en sus microprocesadores. La siguiente versión de Intel poseía mismo juego de instrucciones, velocidad de procesamiento similar, pero a diferencia del 8008, era capaz de direccionar hasta 1,048,576 bloques de memoria (1MB), Intel lo nombró µP 8088. La forma en que Intel aumentó su capacidad de direccionar memoria fue manipulando dos de sus registros de 16 bits para seleccionar localidades de 20 bits, para ello ideó un sistema lógico-físico de direccionamiento.

La compañía Apple, recientemente formada por Steve Jobs y ¿?????? armaron una computadora para uso casero (computadora personal ó PC por sus siglas en inglés) usando el µP 6800 de Motorola, un mes después la compañía IBM (fundada en ‘???? por ¿???) saca al mercado una PC basada en el procesador 8088 de Intel. Las PC de ambas compañías se comercializan con gran éxito durante un par de años, sin embargo ocurre un evento sustancial, hacia 1984 tanto Intel como Motorola adquieren la experiencia y técnica necesaria como para dar un salto en el diseño y fabricación de microprocesadores, significando con esto obtener un canal de datos y de direccionamiento mayor, así como en en los registros internos del mismo, todo ello significando mayor. Cada µP posee su propio conjunto de instrucciones (juego de instrucciones), el juego de instrucciones mas conocido es el del µP 8088 del fabricante de semiconductores INTEL. La familia de µP 8088 es empleado en las computadoras personales (PC) compatibles con IBM, emplearlo necesariamente requiere conocer la parte física de la maquina: el hardware (su construcción); y sobre la que trabajara: el software (lo abstracto). El software básicamente se enfoca al manejo de memoria, esto es:

La memoria interacciona entre el CPU y el sistema de E/S. Los programas se cargan en memoria, se relocalizan y se ejecutan. – El primer modelo pasa el manejo de memoria es la “maquina desnuda” que tiene un control completo sobre la memoria. Esto implica un sistema con aplicación especifica – El segundo modelo es el de “monitor residente”, se divide la memoria en dos secciones, una para el usuario y otra para el S.O. Esto implica un sistema para aplicaciones múltiples. Al encender la maquina se ejecuta un programa llamado “boot strap loader”, el cual se carga a sí mismo, esto lo hace leyendo los primeros 512 bytes de un disco. Al encender la maquina o en el reset, el µP inicia direccionando la parte mas alta de la memoria (FFFF0 -coloca en el registro CS: F000 e ip: FFF0-), ésta localidad de memoria corresponde físicamente al ROM. El µP lee el contenido de esta dirección mediante el ducto de datos. La instrucción que se encuentra es un salto lejano hacia la dirección F000: E05B lugar de la memoria en la que se encuentra la secuencia de rutinas del POST (Power On System Test) la cual es un programa que se encarga de ejecutar pruebas e inicializar la circuitería tanto de la tarjeta madre como la de los periféricos. El grado y forma de probar/inicializar varia dependiendo de los diferentes BIOS existentes pero en general la secuencia es la siguiente:

- Checa los registros del CPU - Configura temporizador para la RAM dinámica. - Configura el DMA para refrescar le RAM dinámica.

- Verifica que la actualización de RAM dinámica este operando. - Prueba la parte baja de la RAM (16-64 KB). - Cargar los vectores de interrupción y conseguirá un área stock en la parte baja de le

RAM. - Inicializa dispositivos de video y teclado. - Prueba y verifica el tamaño de la RAM restante. - Inicializa los puertos COM, LPT y des juegos. - Inicializa el sistema de disco flexible. - Inicializa el sistema de disco duro. - Llama a la interrupción de ejecución de Bootstrap.

Si la prueba encuentra algún error el programa regresa señales audibles (beeps), por lo que se tienen diferentes códigos de beeps dependiendo del tipo de error encontrado (aproximadamente 45 diferentes para errores fatales). Bootstrap En caso de no encontrar errores o ninguno fatal, el programa genera la interrupción 19 de ejecución de “boostrap loader”, el cual es un programa que lee el contenido de los primeros 512 bytes de un disco cargándolos en memoria para ser ejecutados. Extensiones del BIOS: En termines generales el POST revisa las funciones individuales del procesador, sus registros y algunas instrucciones. Si existe error, el sistema se detiene sin mostrar ningún indicio visual o audible. A continuación se revisa el mismo código del BIOS y allí no hay error continua con los dispositivos de la tarjeta madre (RAM, controlador de interrupciones, controlador DMA temporizador, etc.). Continua con dispositivos periféricos como teclado, unidades de disco, puertos serie y paralelo, etc. Finalizando las pruebas, empieza la búsqueda para las extensiones del BIOS. Por ejemplo, las tarjetas de video EGA, VGA o SVGA tienen sus propias funciones de BIOS que reemplazan a la interrupción original 10 N del BIOS (la que en realidad esta diseñada para manejo de tarjetas MDA y CGA). Otros dispositivos como los controladores para discos duros colocan las suyas reemplazando la int 13 del BIOS. El POST hace pruebas buscando extensiones de ROM revisando los desplazamientos 00 y 01 del rango de memoria reservado para funciones de BIOS. Si el contenido de estos 2 bytes son 55H y AAH respectivamente, el POST asume que existe código ejecutable en donde el desplazamiento 02 indica el tamaño de la ROM en bloques de 512 bytes. El programa ejecutable propiamente empieza en el desplazamiento 03N. Los últimos 2 bytes del total de bloques de 512 bytes de la memoria deben indicar un “checksum” del contenido. En general el formato es el siguiente: 55, AA, 40 ←40Hx512Byts=8000 Call C000 : 1F4E ↓ RETF ––––– ––––– ––––– –––––

––––– BC, 4F ← Checksum Estos módulos de ROM pueden reemplazar las rutinas originales del BIOS y en dado caso tomar los recursos de la maquina para una aplicación especifica. Rangos para extensiones del BIOS:

- El primer rango va de C000:0000 – C000:7FFF. Esta es una extensión reservada para extensiones de BIOS dadas por las tarjetas VGA, EGA y SVGA.

- El segundo rango va de C000:8000 – D000:HF. Esta se reserva para extensiones de BIOS dadas por controladores de disco duro. Generalmente el segmento que va de D000:0000 – D000:FFFF se usa para paginas de memoria en tarjetas EMS (para rango de memoria extendida) por lo que si es una tarjeta de éste tipo, este segmento no estará disponible.

- El tercer rango va de E000:0000 – E000:FFFF y se reserva para sistemas con bios de diferente índole (misceláneos). Al terminar las inicializaciones del bios el proceso que continúa es el de arranque de sistema, se lleva a cabo generando la int 19h y conocido como “bootstrap loader” el cual intenta cargar alguna forma de sistema operativo básico. Este es el punto al que se transfiere el control cuando se oprime <CTRL><ALT><DEL> hacia algún disco determinado. Si no existe disco o es de arranque, entonces esta rutina busca otra unidad de deseo conectada a la PC o a una localidad determinada en el disco duro existente. Si no encontrase se envía el mensaje de “insertes un disco con sistema y oprimes una tecla”. A continuación se carga a memoria el código encontrado a inicio del disco. Esta parte del disco es comúnmente la que “infectan” los virus de computadoras, colocan como primer instrucción su salto hacia su propio código para ser ejecutado al cargarse esa parte en memoria. También éste lugar del disco es donde se coloca los programas administradores de arranque, con ellos es posible decidir que sistema operativo se desea arrancar cuando existen varios de ellos en el disco duro. En términos generales la memoria de la computadora queda dividida de la siguiente manera:

Vectores de Interrupciones

Tabla de vectores de interrupción (768 Bytes)

00000

00000 1 KByte

002FF

Área de stack para BIOS

(256 bytes)

05000

0FFFF

Memoria de Aplicación (640KB)

00000

001DF

Tabla de vectores de interrupción (480 Bytes)

A0000

BFFFF

VRAM para EGA y VGA (128 KB)

001E0

002FF

Tabla de vectores de usuario

(288 Bytes) C0000

C7FFF

Área de expansión de ROM BIOS de video

(32 KB)

00300

003FF

Área de Stack de BIOS

(256 Bytes) C8000

C8FFF

Adaptador ROM (32 KB)

00400

004FF

Área de Datos de BIOS

(256 Bytes) D0000

DFFFF

Adaptador de ROM (64 KB)

00500

005FF

Uso de DOS (256 Bytes)

(Si S.O. DOS es el residente)

E0000

EFFFF

Ext. de BIOS, Redes o Adaptador de ROM

(64 KB)

00600

9FFFF

Memoria RAM para usuario

(638 KB) F0000

BIOS

(64 KB) ← FFFF0 Dirección de arranque

FFFFF

del µP

En el área de datos del BIOS se encuentran las direcciones de los dispositivos. Estos datos se encuentran en memoria entre las direcciones 0040:0000 – 0040:00FF por lo que teniendo dirección de base 00400 (0040:0000) cada 2 bytes se tiene: Corrimiento:

00 - Dirección del COM1 02 - Dirección del COM2 04 - Dirección del COM3 06 - Dirección del COM4 08 - Dirección del LPT1 0A - Dirección del LPT2 0C - Dirección del LPT3 0E - No usado (apuntador a datos de extensión de bios) 10 - Dirección de equipamiento variable- no usada 12 - tamaño de memoria en bloqueo de 1 Kbyte 15 - no usada 17 - bandera1 de teclado 18 - bandera2 de teclado 19 - buffer de la tecla <ALT> 1A - inicio del buffer de teclado 1C - final del buffer de teclado 1E - buffer del teclado 3E - bandera de recalibracion del floppy 3F - estado del motor de floppy 40 - contador del apagado del motor de floppy 41 - byte de estado del floppy 42 - bytes de estado del floppy

REGISTROS DEL ΜP Se dividen en:

- registros de uso general - registros apuntadores y de índice - registros de segmentos

Existe un registro de banderas que señala el estado de la unidad aritmética y lógica (ALU). Registros de propósito general Para el uso que más convenga al usuario. Se pueden direccionar como de 8 bits (AW, AL, BW, BL, CN, CL, DN y DL) o como de 16 bits (AX, BX, CX y DX). En los µP 80386 y 80486 además pueden direccionarse como de 32 bits (EAX, EBX, ECX y EDX). Aunque se emplean por uso general tienen tareas específicas, de esto su nombre. - AX (acumulador): comúnmente conserva el resultado temporal después de una operación

aritmética. También puede contener la dirección de desplazamiento de una localidad en el sistema de memoria (EAX)

- BX (índice de base): comúnmente conserva la dirección base de los datos que hay en memoria. En el EBX puede direccionar datos de memoria.

- CX (contador): contiene el valor de conteo de ciertas instrucciones. En el ECX puede contener la dirección de desplazamiento de los datos de memoria.

- DX (datos): comúnmente contiene la parte más significativa de un producto o la de una división así como el número de puerto E/S.

Registros apuntadores e índices Se utilizan generalmente para apuntar a la localidad de memoria que contiene los datos del operando en muchas instrucciones, estas son:

- SP (apuntador de pila): Direcciona datos en memoria funcionando como pila LIFO (ultimo en entrar, primero en salir) la cual se emplea al usar instrucciones push y pop.

- BP (apuntador de base): Usado comúnmente para direccionar un conjunto de datos en memoria.

- SI (índice de fuente): Usado para dimensionar datos (de origen) para usarse en instrucciones de cadenas o arreglos.

- DI (índice de destino): Direcciona datos (de destino) para usarse en instrucciones de cadenas o arreglos.

- IP (apuntador de instrucciones): Direcciona siempre la siguiente instrucción a ejecutar el µP. El apuntador puede ser modificado con una instrucción de salto o de llamada de subrutina.

- FLAGS (banderas): Indica la condición del microcontrolador y controla su operación. Registros de segmentos Estos generan direcciones en la memoria al combinarse con otros registros del µP

- CS (código): Indica el segmento de memoria que contiene el código del programa. Define la dirección inicial de la sección de memoria que contiene el código

- DS (datos): Indica el segmento de memoria que contiene los utilizados por el programa. Se accede a los datos por medio de un desplazamiento o a través del contenido de otros registros que contienen la dirección de desplazamiento.

- ES (extra o adicional): Lo utilizan algunas instrucciones de cadenas para constituir el destino de los datos

- SS (pila): Indica el segmento de memoria utilizada para la pila. El punto de entrada de la pila esta definido por los registros de este segmento, así como por los registros de los apuntadores de pila.

Nombres de 32 bits

Nombres de 8 bits

Nombres de 16 bits

Nombres de 8 bits

EAX AH -AX- AL Acumulador EBX BH -BX- BL Índice de base ECX CH -CX- CL Contador EDX DH -DX- DL Datos ESP SP Apuntador de pila EBP BP Apuntador de base EDI DI Índice destino ESI SI Índice de fuente

EIP IP Apuntador de instrucción

EFLAGS BANDERAS Banderas

CS Código DS Datos ES Extra SS Pila FS

GS

- FS y GS: Registros de segmentos complementarios que permiten que los programas accedan a dos segmentos de memoria adicionales.

Registro de banderas Es un registro en el que cada bit indica un estado particular del µP, estos son:

- C (acarreo): Indica que hubo acarreo después de una suma o un “préstamo” después de una resta. Tambien indica condiciones de error, según lo establezcan algunos programas o procedimientos.

- P (paridad): Es 0 para paridad impar y 1 para la par. La paridad es el conteo de unos en un numero así por ejemplo un digito 01101 tiene paridad impar y el numero 11011 es de paridad par.

- A (acarreo auxiliar): Se “enciende” si en una operación de suma o resta existe un acarreo o un préstamo respectivamente entre las posiciones de los bits 3 y 4 del resultado. Esta bandera ajusta el valor posteriormente del registro AL

- Z (cero): Indica si el resultado de una operación aritmética o lógica es cero. Si Z=1, el resultado es cero; si Z=0, el resultado es diferente de cero

- S (signo): Indica el signo aritmético del resultado después de una operación aritmética o lógica. Si S=1, el bit del signo (el bit del extremo izquierdo de un número) se encuentra activado o es negativo; si S=0, el bit de signo esta inactivado o es positivo.

- T (trampa): Habilita la función de captura de errores por medio de una característica de depuración del µP. Si la bandera T esta habilitada (1), el µP interrumpe el flujo de un programa bajo las condiciones especificadas en los registros de depuración y los de control. Si T esta en cero lógico, la función de depuración se encuentra deshabilitada.

- I (interrupción): Controla la operación de la terminar de entrada INTR(solicitud de interrupción). El estado del bit de bandera I es controlado por las instrucciones STI (activar bandera de interrupción) y CLI (borrar bandera de interrupción)

- D (dirección): Controla la selección de incremento o decremento de los registros DI o SI en instrucciones de cadenas. Si D=1, los registros disminuyen automáticamente; si D=0, los registros aumentan automáticamente. La bandera D se activaron la instrucción STD(activar bandera de dirección) y se desactiva con la instrucción CLD (borrar bandera de dirección)

- O (sobre flujo): Se actúa si ocurre un sobre flujo al sumar o restar números con signo y se excede la capacidad de la maquina

El formato del registro es: 0 D I T S Z A P C

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

31 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

ID VIP VIF AC VM RF NTIOP

1 IOP

0 O D I T S Z A P C

←––––8086/8088/80186/80188–––––––→ ←––––––––––––––––––––––80286––––––––––––––––→ ←––––––––––––––––––––––––––––––––80386/8986DX––––––––––––→ ←––––––––––––––––––––––––––––––––––––––80486SX–––––––––––––––→ ←––––––––––––––––––––––––––––––––––––––––––––––––Pentium/Pentium II–––––––––––→

- IOPL: (nivel de privilegio de E/S) Dependiendo el nivel de privilegio actual, determina si se ejecuta E/S sin impedimento o si es menor que el nivel actual, y ocurre una interrupción.

- NT (tarea anidada): Señala que tarea actual esta anidada pro software dentro de otra, en el modo protegido de operación.

- RF (reanudar): Se utiliza durante la depuración para controlar la reanudacion de la ejecución después de la siguiente instrucción.

- VM (modo virtual): Selecciona la operación en modo virtual de un sistema que se encuentra en modo protegido, permitiendo la coexistencia en memoria de múltiples particiones del DOS

- AC (verificación de alineación): Se activa al direccionar una palabra o una doble palabra en una dirección que no es un número par (para palabras) o múltiplo de 4 (para palabras dobles)

- VIF (bandera de interrupción virtual): Copia del bit de bandera de interrupción - VIP (interrupción virtud pendiente): proporciona información sobre una interrupción en

modo virtual o interrupciones pendientes. - ID (identificación): Señala la aceptación de la instrucción CDPUID (instrucción que

proporciona al sistema información sobre el microprocesador, tal como el num. de versión y el fabricante)

Modos de direccionamientos Los modos de direccionamientos de datos incluyen los de:

- registro - inmediato - directo - indirecto por registro - base mas índice - relativo por registros - relativo por base más índice

Los modos de direccionamiento de memoria de programa son: - relativo al programa - directo - indirecto

Modos de direccionamiento de datos Para explicarlos se usa la instrucción mov usada de la siguiente forma: mov destino, fuente

- Direccionamiento por registro: Transfiere el dato de un registro a otro registro. Por ejemplo: mov cx, dx

- Direccionamiento inmediato: Transfiere un dato (constante) a un registro. Por ejemplo: mov al,22

- Direccionamiento directo: Transfiere un dato entre una localidad de memoria y un registro. Por ejemplo: mov cx,[ab23]

- Direccionamiento indirecto por registro: Transfiere un dato entre un registro a una localidad de memoria direccionada por bx. Por ejemplo: mov ax, [bx]

- Direccionamiento base mas índice: Transfiere un dato entre un registro y una localidad de memoria direccionada por un registro base (BP o BX) + un registro índice (DI o SI). Por ejemplo: mov [BX + di], cl

- Direccionamiento relativo por registro: Transfiere un dato entre un registro y una localidad de memoria direccionada por un registro índice o un registro de base + un desplazamiento. Por ejemplo: mov ax,[bx + 4]

- Direccionamiento relativo base mas índice: Transfiere un dato entre un registro y una localidad de memoria direccionada por un registro índice o un registro de base + un índice + un desplazamiento. Por ejemplo: mov ax,[bx + di + 4] Modos de direccionamiento de memoria de programa. Se utilizan en las instrucciones jump (salto) y call (llamada), tiene 3 configuraciones distintas: directa, relativa e indirecta.

- Direccionamiento directo a la memoria del programa. Se utiliza en los µP en los saltas incondicionales (brincos) y llamadas. Las instrucciones que realizan direccionamiento directo a la memoria almacenan la dirección junto con el código de operación. Por ejemplo: jmp F000:FFF0 o call F000:FFF0 Estas instrucciones cargan cs con F000 e ip con FFF0; el brinco (jmp) cuando se realiza entre segmentos (como el del ejemplo) se dice que es un “brinco lejano” y cuando solo es dentro de su mismo segmento se dice que es un “brinco cercano” como por ejemplo: jmp 0100 en el que solo carga ip con 0100.

- Direccionamiento relativo de memoria de programa. El termino “relativo” indica “relación con el ip”. Por ejemplo: jmp[2] carga en ip = ip + 2 de tal forma que se “brinca” el numero de bytes indicados desde donde actualmente se encuentra. Cuando el “brinco es corto” el desplazamiento es de solo un byte (cuyo valor esta entre +127 y –128); si el “brinco es cerceno” el desplazamiento es de 2 bytes (en tal caso el valor esta entre +32k y –32k). Los ensambladores calculan en forma automática la distancia del desplazamiento y seleccionan el tipo de direccionamiento relativo (1 o 2 bytes y hasta 4 bytes en µP 386 y 486).

- Direccionamiento indirecto de memoria de programa. De la familia de µP 8086 permite cierto numero de formas de direccionamiento indirecto de la memoria de programa usando las instrucciones jmp y call, lo que se realiza usando cualquier registro (AX, BX, CX, DX, SP, BP, DI, o SI) o relativo a registro ([BP], [BX], [DI], o [SI]) y registro relativo con un desplazamiento, así por ejemplo:

jmp ax -brinca a localidad direccionada por ax del segmento actual jmp [bx] -brinca a localidad del segmento actual almacenada en ds:bx jmp[di + 2] -brinca a localidad (del segmento actual) almacenada en la dirección ds: di +

2 jmp saltos [bx] -brinca a la localidad (en el segmento actual) direccionada por salto + bx donde saltos dw A0C0 dw F0C1 dw 00C2

dw B0C3 - Direccionamiento de la pila de memoria. La pila de memoria emplea el sistema LIFO

(ultimo en entrar, primero en salir), los datos se colocan en la pila con una instrucción push y se recuperan con una pop. La instrucción call usa la pila para guardar la dirección de la que partió y la instrucción ret recupera de la pila la dirección a la que hay que retornar. Así por ejemplo si se hace:

mov ax, F000

push ax mov ax, FFF0 ret se colocan en cs: ip tales valores. La pila de memoria se mantiene con el registro sp (apuntador de pila) y el ss (segmento de pila) formando la dirección ss:sp Instrucciones para transferir datos (uso de mov) El mas común es empleando la instrucción mov. Por ejemplo: mov dl,[di] : transfiere el contenido de la memoria de datos al registro dl. mov [1000],dl :transfiere el contenido del registro dl a la localidad de memoria 1000 del

segmento de datos. mov word ptr[bx+0100],al : esta instrucción transfiere el contenido del registro al al la

localidad de memoria de tamaño de palabra direccionada por ds:bx0100. mov byte ptr[bx+0100],dl : igual a la anterior pero ahora es apuntador a memoria de tamaño

de un byte. Uso de la instrucción push En µP 8086 y 286 transfiere 2 bytes de datos a la pila y en µP 80380 y 486 transfiere 2 o 4 bytes según sea el tamaño del registro o la localidad de memoria. PUSH salva en la pila cualquier registro interno, datos inmediatos o datos de memoria. pusha ► salva todos los registros internos excepto al de segmento de pila. Los almacena en el orden ax, cx, dx, bx, sp, bp, si, di. pushf ► salva registro de bandera. pop ► (lo contrario de push), transfiere datos de la pila y los carga en los distintos que pueden ser registros o localidad de memoria. popf ► recupera el dato en pila y coloca en registro de banderas. popa ► recupera todos los registros en el orden di, si, bp, sp, bx, dx, cx y ax. LEA – carga un registro con la dirección de desplazamiento de los datos especificada en el operando. Por ejemplo lea bx,[di] ► carga el contenido de [di] en ax es muy parecido a mov y es equivalente en la instrucción en el ejemplo que mov bx,offset tabla lea bx,tabla cargan la dirección de desplazamiento de la localidad “tabla” de la memoria en bx. LSD – (solo para 386 y 486) carga registros con una dirección de desplazamiento y al registro ds. Ejemplo: lds bx,[di] ► carga el dato de 32 bits en [di] en bx y ds. LES, LFS, LGS y LSS se usan como lo anterior pero cada una empleada con su respectivo segmento. Transferencia de cadenas de datos. LODS – carga al o ax con datos almacenadas en la dirección de desplazamiento dada por si en el segmento de datos. Ejemplo: LODS Lista ► se hace Al=[si] LODSB Lista ► se hace al=[si] cargando solo un byte LODSW Lista ► igual pero carga una palabra en ax

STOS – almacena al o ax en el segmento extra en la localidad direccionada por el registro di. Ejemplos: STOSB [di] ← al STOSW [di] ← ax Si se usa REP hace que se repita la instrucción de cadena decrementandose cx hasta que cx = 0 y dado que di se autoincrementa o autodecrementa dependiendo de la bandera de dirección D (D = 0 autoincrementa). MOV – transfiere datos de una localidad a otra en memoria. Es la única transferencia de memoria a memoria que realiza el µP. Se transfiere un byte o palabra desde la localidad DS[SI] a la localidad ES:DI. Ejemplos: mov sb ► transfiere un byte de [DI] ← [SI] mov sw ► transfiere una palabra de [DI] ← [SI] XCHG – intercambia el contenido de un registro con el otro o alguna localidad de memoria. Por ejemplo: xchg[di],ax ► hace [di] ↔ ax No funciona con registros de segmentos ni intercambio entre localidades de memoria. XLAT – carga en el registro al dato en memoria cuya dirección es [Alt+bx] asi xlat hace al ← [al+bx] IN – transfiere un dato desde un dispositivo de E/S al registro al o ax del µP. Por ejemplo: in ax,dx o in al,0B10 OUT – transfiere un dato en al o ax a un dispositivo de E/S. Por ejemplo: out 0B10,ax o out dx,al. Para hacer cambios de segmentos al que se refiere una instrucción de movimiento de datos se añade al principio de una instrucción un prefijo con el segmento al que se hace referencia, asi por ejemplo: mov ax,[di] hace ax ← [di] el dato se obtiene del segmento de datos mov ax,cs:[di] el dato se obtiene del segmento de código Instrucciones aritméticas y lógicas ADD – suma binaria. Ejemplos add al,bl → al = al + bl add bx,0ABC → bx = bx + 0ABC add [bx+di],dl → contenido de [bx+di] = contenido de [bx+di]+dl en la operación de suma se modifica el contenido de las banderas de signo, cero, acarreo auxiliar, paridad y sobreflujo del registro de banderas. INC – suma de incremento, se agrega un 1 a un registro o a una localidad de la memoria. Esta instrucción puede sumar 1 a cualquier registro o localidad de la memoria excepto a registro de segmento. Por ejemplo: inc di → di = di + 1 inc ax → ai = ai + 1

ADC – suma binaria con acarreo, igual que add pero además suma el bit de la bandera C de acarreo a los datos des operando. Por ejemplo: adc al,ah → al = al + ah + acarreo adc [bx],dh → [bx] = [bx] + dh + acarreo SUB – resta binaria. Por ejemplo:

sub cl,bl → cl = cl - bl sub ax,sp → ax = ax – sp sub [di]’A6 → [di] = [di] – A6

DEC – resta un 1 a un registro o al contenido de una localidad de memoria. Por ejemplo: dec bx → bx = bx – 1 dec sp → sp = sp – 1

dec [di] → [di] = [di] – 1

SBB – resta con préstamo, igual que una resta pero ahora al resultado también se le resta la bandera de acarreo. Por ejemplo: sbb ah,al → ah = ah - al - acarreo sbb ax,cx → ax = ax - cx - acarreo sbb di,[bx] → di = di – [bx] – acarreo CMP – comparación, es una resta que solo afecta los bits de bandera, se compara el contenido de un registro o el de una localidad de memoria contra otro valor. No se permiten comparaciones entre localidad de memoria y con registros de segmento. Por ejemplo: cmp cl,bl → cl – bl y solo cambian las banderas cmp [di],ch → [di] – ch y solo cambian las banderas cmp ax,CA01 → ax-CA0 y solo cambian las banderas IMUL – multiplicación de enteros con signos; el producto requiere encontrarse en al, el resultado se encuentre en ax. Por ejemplo: imul [bx] → ax = al * [bx] imul dh → ax = al * dh imul di → dx_ax = ax * di MUL – multiplicación de enteros sin signo. Por ejemplo: mul cl → ax = al * cl mul cx → dx_ax = ax * cx IDIV – división de enteros con signo, el dividendo se encuentra en ax, en al regresa el cociente y en ah el residuo. Por ejemplo: idiv bl →

idiv si →

DIV – división de enteros sin signo. Por ejemplo: div cl →

div cx →

Instrucciones lógicas básicas Estas instrucciones proporcionan el control directo de los bits de algún dato. Las operaciones lógicas afecten el registro de banderas haciendo cero la de acarreo y sobreflujo y las restantes dependen del resultado de la operación. AND – Ejecuta multiplicación lógica genera un 1 si la entra es 1 y 0 en el otro caso. Se emplea para borrar los bits de algún dato. Así por ejemplo: mov al,37 and al,0F → enmascara los 4 bits mas significados de al por lo que al = 7 por lo que se usa para convertir números ASCII a BCD and ax,[di] o and [bx],cl OR - Suma lógica, genera un 1 de salida si cualquiera de las entradas es 1. La salida es cero solo si ambas son cero. Por ejemplo: or ah,bl or dx,[bx] or [bx],cl XOR – Es un or exclusivo. Si ambos entradas son iguales la salida es 0 y si son diferentes la salida es 1. La instrucción se usa para invertir o complementar un dato. Por ejemplo: xor ch,cl xor dx,[si] xor bx,0FA3h TEST – Efectúa la operación AND pero no realiza el cambio en a prueba por lo que solo afecta el registro de banderas. Es muy similar a la instrucción cmp (comparar). La instrucción hace variar el bit cero del registro de banderas; al igual que ‘cmp’ test se usa antes de las instrucciones de salto. Por ejemplo: test al,1 → prueba bit menos significativo jnz otro → si no fue cero salta a ‘otro’ test al,128 → prueba bit mas significativo jnz mas → no es uno salta a ‘mas’ (para únicamente los 386 y 486) { BT – “Bit test”, prueba un bit del operando destino (especificado) en el operador fuente. Por ejemplo: bt ax,2 → prueba bit 4 de ax BTC – Prueba y complementa el bit del operando destino especificado en el operando fuente. Por ejemplo: btc ax,3 → prueba y complementa el bit 3 de ax.

BTR – Prueba y hace 0 el bit del operando destino especificado en el operando fuente. Por ejemplo: btr ax,1 → prueba y hace cero el primer bit de ax. } NOT – Inversión lógica (complemento a uno), contiene un solo operando el cual se le invierte todos los bits. Por ejemplo: not ax → invierte los bits de ax not [bx] → invierte los bits de dato en [bx] NEG – Inversión aritmética con signo (complemento a dos), se efectúa el complemento a dos del operando por lo que el signo del dato se invierte. Por ejemplo: neg ch → ch se complementa a dos neg [dl] → [dl] se complementa a dos Instrucciones de corrimiento Mueven o colocan números a izquierda o derecha dentro de un registro o localidad de memoria. SHL – corrimiento a la izquierda. Por ejemplo: shl ax,2 (1 o cl) → hace corrimiento lógico de ax 2 lugares a la izquierda. SHR – corrimiento lógico a la derecha. Por ejemplo: shr bx,3 (1 o cl) → hace corrimiento a la derecha de 3 posiciones. SAL – corrimiento aritmético a la izquierda, es igual a shl. SAR – corrimiento aritmético a la derecha por lo que el signo se copia igual (no se pierde). Complemento a 2 Se emplea para representar números con signo: Los números enteros son signo. Un registro de 16 bits representa cualquier numero entero entre 0 y 65535 (216-1), si el bit mas significativo se emplea para indicar el signo del numero, entonces el mayor dato entero que puede representarse es de 15 bits mas uno de signo, o sea, datos entre -32767 y +32767. El µP utiliza aritmética con el complemento a 2, en parte, los números positivos se representan de manera normal y los negativos por su complemento. Por ejemplo, el número -79 se representa:

01001111b → 79d complemento a 1 10110000b → se invierten todos los bits representativos + 1b → se agrega 1 para complemento a 2 10110001b = – 79d La representación es útil para realizar operación aritméticas, por ejemplo: Si se desean restar los números 57d – 23d = 34d

Si representamos el –23d por su complemento a 2. La misma operación puede realizarse como una suma, esto es: 57d + (76 + 1) = 57d + 77d = 134d

↑ se elimina el digito más significativo el cual es el acarreo

Rotaciones: Estas instrucciones hacen “rotar” los bits del dato en un registro o localidad de memoria. ROL – Rota a la izquierda los bits en una localidad de memoria o registro. Los bits que salen del registro se colocan al principio del mismo. Ejemplo: rol si,1 → rota si en un lugar a la izquierda rol ax,cl → rota ax a la izquierda el numero de lugares indicados en cl ROR – Rota a la derecha los bits de una localidad de memoria o registro. Los bits que salen del registro se colocan al final del mismo. Ejemplo: ror [bp],cl → rota el dato en [bp] cl veces a la derecha. ror bx,1 → rota bx de un lugar a la derecha RCL – Similar a ROL pero el dato rota además a trabes del bit de acarreo del registro de banderas. Ejemplo: rcl bl,1 → rota el dato en bl 1 vez a la derecha rcl ax,cl → rota el dato ax el numero de veces indicado en cl a la izquierda RCR – Similar a ROR pero el dato rota además a través del bit de acarreo del registro de banderas. Ejemplo: rcr ah,cl → rota ah el numero de lugares indicado en cl. Instrucciones para rastreo de bits (solo en µP 386 y 486) Estas instrucciones realicen una rotación de los bits de un operando buscando un 1. BSF – Rastreo hacia delante el cual realiza la operación rol buscando el primer bit que sea a uno, si se encuentra en 1 la instrucción pone a 1 la bandera de cero del registro de banderas y la posición de dicho bit se carga en el operador de destino. Por ejemplo: bsf ax,cx → en cx se pone el numero del bit donde se encuentro el primer 1 de ax. En caso de no encontrar ningún 1 las instrucciones coloca 0 en el bit de cero del registro de banderas. Instrucciones para comparación de cadenas Permiten probar el registro al, contra un dato en memoria. SCASW – Igual que el anterior pero ahora es para palabra por lo que usa el registro ax. SCASD – Igual que los anteriores pero para dobles palabras por lo que se compara el registro EAX (solo para el µP 386 y 486). Estas instrucciones pueden usar la bandera de dirección (D) del registro de banderas para seleccionar incrementos o decrementos automáticos del registro DI así usando un prefijo es posible repetir una búsqueda a lo largo de un bloque de memoria completo. Por ejemplo: mov di,0140

mov cx,0100 mov al,55 repne scasb Se apunta a una localidad de memoria, el contador se pone a 100 y se busca el dato 55 a lo largo de todo ese bloque de memoria. El prefijo repne (repite mientras no sea igual) hace que la instrucción scasb se repita mientras cx no sea cero o hasta que exista la condición de igualdad. El otro prefijo que puede usarse es repe (repetir mientras sea igual). CMPSB – compara un byte en memoria direccionado por si se compara con el contenido de memoria direccionado por di. CMPSW – Igual al anterior pero para palabras CMPSD – Igual que los anteriores pero para dobles palabras (solo µP 386 y 486). Instrucciones de control de flujo Saltos: Es un grupo de instrucciones para control del programa y que permita saltar secciones de un programa transfiriendo el control a otra parte de la memoria. Se ejecutan cálculos numéricos y basados en el resultado de estos los bits del registro de banderas cambian y estos son los indicadores para ejecutar o no un salto. JMP – Salto incondicional. No depende de ninguna bandera del registro de banderas para llevarse a cabo, puede ser de tres tipos:

- corto - cercano - lejano

El salto corto ocupa 2 bytes así lo que permite transferir el programa a localidades entre +127 y –128 bytes desde la localidad donde esta la instrucción. El salto lejano es una instrucción de 3 bytes así que permite cambiar el flujo hasta de -/+32 Kbytes desde donde se localiza la instrucción. El salto lejano es una instrucción de 5 bytes permitiendo brincar a cualquier localidad de memoria dentro de la maquina. En µP 386 y 486 el brinco corto esta entre +/- 2 Gbytes si se trabaja en el modo protegido y de 4 Gbytes si es lejano. Salto Corto Un salto corto se le llama también “salto relativo” porque se da hacia la misma dirección la misma distancia encuéntrese en donde se encuentre la instrucción ya que la dirección a la que se salta no esta en el código de operación sino que se almaneca el código y el desplazamiento a ejecutarse, entonces: [codigo/desplazamiento] como por ejemplo jmp 100 de tal forma que al registro ip se la suma el desplazamiento. Salto Cercano Similar al anterior pero ahora la distancia se encuentra dentro del tamaño del segmento de código, ocupa un byte para el código y dos bytes para el desplazamiento por lo que el salto es de una distancia de 16 bits con signo o sea +/-32 Kbytes de distancia e el salto. En los µP 386 y 486 el desplazamiento es de 32 bits con el signo o sea +/- 2 Gbytes.

Una característica importante de ambos tipos de salto es que al ser relativos al punto donde se origina esto permite que el código colocado en cualquier parte de la memoria y funcionar apropiadamente, esto se le llama programa relocalizable por lo que un S.O. puede cargarlo en cualquier parte de la memoria. Salto Lejano Estos ocupan un byte de le instrucción y 4 con la dirección hacia donde se desea saltar, esto implica desplazarse a cualquier parte de la memoria (salto entre-segmentos). Brincos condicionales En µP 386 y 486 los brincos condicionales son cortos y en 386 y 486 pueden ser cortos o cercanos. Las instrucciones de brinco condicional prueban las banderas de signo cero o acarreo o paridad o sobreflujo y si la condición es verdadera se ejecuta la transferencia. Estas son: ja c = 0 y z = 0 salta si esta por arriba de jae c = 0 salta si esta arriba o no es igual a jb c = 1 salta si esta por abajo de jbe c = 1 o z = 1 salta si esta por abajo o es igual a jc c = 1 salta si hubo acarreo je o jz z = 1 salta si fue igual a cero jg z = 0 y s = 0 salta si es mayor a jge s = 0 salta si es mayor o igual a jl s ≠ 0 salta si es menor que jle z = 1 o s ≠ 0 salta si es menor o igual a jnc c = 0 salta si hubo acarreo jne o jnz z = 0 salta si no fue igual a o no fue cero jno o = 0 salta si no hubo sobreflujo jns s = 0 salta si no hay signo jnp/jpo p = 0 salta si no hay paridad o fue impar jo o = 1 salta si no hubo sobreflujo jp/jpe p = 1 salta si hay paridad js s = 1 salta si hay signo jcxz cx = 0 salta si cx = 0 jecxz ecx = 0 salta si ecx = 0 LOOP – Es realmente un decremento de cx y un brinco condicionado, esta instrucción decrementa cx y si este no es igual a cero brinca a la dirección especificada. En µP 386 y 486 se usa LOOPW para usar el registro cx y LOOPD si se usa ecx. LOOPE – Es un loop condicional (similar al “rep”) “repite mientras sea igual”, el ciclo se mantiene mientras la condición sea igual o cx no sea cero y sale del ciclo si la condición no es igual o cx es cero, por ejemplo: mov cx,10 otro : cmp ah,al loop otro → salto a ‘otro’ si cx = 0 y se cumple la comparación LOOPNE – Similar al anterior pero ahora el salto se da si a condición no es igual o cx ≠ 0.

CALL Transfiere el flujo del programa a un procedimiento (o subrutina), al ejecutarse se salvan en la pila la dirección para el retorno y se regresan con la instrucción “net”.

Memoria 0000

S. O.

cs:ip →

Código

ds:bx →

Datos Programa

ss:sp →

Pila

Extra es → FFFFF

Call Cercano Ocupa 3 bytes de longitud. El primer contiene el código de la operación. 2do y 3er el desplazamiento o sea +/- 32 bytes. En 386 y 486 el desplazamiento es de 32 bits o sea +/- 2 Gbytes. Al ejecutar el call cercano se salva en la pila el registro ip y a ip = ip + desplazamiento (igual que jmp cercano). Call Lejano Ocupa 5 bytes uno del código y dos para el desplazamiento por lo que puede saltar 2 pares, el segmento cs a cualquier lugar de la memoria. Al ejecutarse se guarda en la pila el ip y luego is. Call con operandos registro La instrucción call puede contener un operando registro el cual contiene la dirección del salto, por ejemplo: call si call cs:bx RET – Instrucción para retornar de una subrutina, obtiene de la pila un numero de 2 bytes y lo coloca en ip (retorno cercano). En los µP 386 y 486 activos en modo registro protegido extrae 4 bytes de la pila y los coloca en EIP. RETF – Instrucción para retorna de una subrutina, obtiene de la pila 4 bytes y los coloca en cs e ip respectivamente. En los µP 386 y 486 en modo protegido el retorno lejano obtiene de la pila 6 bytes, los primeros 4 se colocan en EIP y los 2 restantes en CS. RET con operando Si se usa ret 8 la instrucción suma el número 8 a SP antes del retorno de tal forma que se extraen no últimos datos metidos a la pila sino anteriores a ellos.

Registros a modificar para desplazarse entre la memoria del código, datos y pila de un programa

INTERRUPCIONES Una interrupción es una llamada generada por algún dispositivo físico del sistema (hardware) o una llamada generada por un programa (software), sea cual sea su origen, el µP detendrá la operación actual y cambiara el flujo de operaciones a otro lugar de la memoria. Vector de interrupción Este es un numero de 4 bytes y se almacenan en los primeros 1024 bytes de la memoria (00000-003FF) que direcciona el µP en modo real por lo que no hay 256 vectores diferentes. Cada vector contiene la dirección de una rutina de servicio (servicio de interrupción). Cada vector contiene un valor de ip y uno de cs con la que se forma la dirección de memoria donde se localiza el servicio de interrupción. Los dos primeros bytes se cargan en el ip y los dos siguientes en cs. Memoria CMOS en la AT El CMOS es un tipo de memoria respaldada con batería por lo que no es volátil, se encuentra ubicada en el mapa de memoria como dispositivo de E/S en las direcciones 070-071 por lo que el acceso a elle es a través de las instrucciones “in” y “out”. Intel reserva los primeros 32 vectores de interrupción para emplearse en el mismo µP (para manejo de errores o excepciones), por ejemplo es posible generar interrupción 0 (la cual es un servicio en caso de división por cero o por sobreflujo). Los primeros 5 vectores de interrupción son idénticos en todos los µP desde 8086 hasta 486. Las interrupciones dedicadas al µP son las siguientes:

- Int 0: división por cero. - Int 1: modo paso a paso o de rampa; se de eso cada ejecución de una instrucción si esta

activo el bit TF (bandera de trampa) de registro de banderas. Al aceptar esta interrupción se borra el bit TF para ejecutar ahora un interrupción.

- Int 2: interrupción de hardware no enmascaradle, se genera l colocar ‘1’ en la terminal NMI del µP.

- Int 3: interrupción de un byte. Ocupa un solo byte y se emplea comúnmente para parar un punto de ruptura en un programa para depararlo (se genera por la bandera TF).

- Int 4: interrupción de sobreflujo. Interrumpe el programa si existe un sobreflujo (la bandera OF en alto).

- Int 5: Bound: Instrucción; compara un registro con dos palabras de datos en memoria. Por ejemplo:

bound ax,[bx]; se genera si ax ≥ [bx] y ax ≤ [bx +1] - Int 6: código invalido. Se genera si se encuentra una instrucción indefinida. - Int 7: Coprocesador no disponible. Se genera cuando no se encuentra un coprocesador

después de ejecutar alguna instrucción ESC o WAIT y no se encuentra el coprocesador. - Int 8: Falta Doble. Ocurre cuando se dan dos interrupciones durante la misma

instrucción. - Int 9: Sobreflujo del segmento del coprocesador; se genera si la instrucción ESC se

extiende mas allá del desplazamiento FFFF. - Int 10: Segmento de estado de tarea no valido; se genera si el segmento de estado de

tarea (TSS) es mayor a 002B.

- Int 11: Segmento no presente, se genera si el bit P ≠ 0 en un descriptor (el segmento no esta presente o no es valido).

- Int 12: Desborde del segmento de piles, se genera si el segmento de pila no esta presente o se ha excedido el limite del mismo.

- Int 13: Protección general. Se genera al ocurre violaciones de la protección del µP activo en modo protegido (µP 8028 a 486), estas violaciones son:

a) Limite excedido de la tabla de descripciones. b) Reglas de privilegio violadas. c) Se cargo un tipo no valido para el segmento del descriptor. d) A escribir en el segmento de código que esta protegido. e) Leer el segmento de solo ejecutar código. f) Escribir el segmento de solo leer datos. g) Limite excedido del segmento. h) CPL ≠ 0 al ejecutar CTS, ALT, LGDT, LIOT, LLDT, LMSW o LTR. i) CPL > IOPL al ejecutar CLI, IN, NS, LOCK, OUT, OUTS y STI

- Int 14: Falla de acceso a pagina; se genera cuando falla el acceso a una pagina de memoria en 386 y 486.

- Int 16: Error del coprocesador; se genera cuando ocurre un error del coprocesador en las instrucciones ESC y WAIT (µP 386).

Generando una interrupción Al ocurrir alguna condición de interrupción ocurre lo siguiente:

1. Se salva el contenido del registro de banderas en la pila. 2. Se desactivan las banderas de interrupción (IF) y de trampa (TF) del registro de

banderas; esto deshabilita la terminal INTR y la característica de trampa. 3. Se salva el contenido del registro cs en la pila. 4. Se salva el contenido del registro ip en la pila. 5. Se recupera el contenido del vector de interrupción colocándolo en ip y cs de tal

forma que la siguiente instrucción que se ejecuta es el código de servicios de la interrupción. Para terminar el código de servicio de la interrupción debe existir la instrucción IRET la cual devuelve el estado original de las banderas IF y TF y se recuperan de la pila los registros cs, ip.

Manejo de la interrupción dependiendo del registro de banderas La bandera de interrupción (IF) y la de trampa (TF) se borran una vez que se salvan en la pila al ocurrir una interrupción. Cuando IF = 1 se permite que de la terminal INTR del µP pueda ocasionar una interrupción. Cuando TF = 1 se ocasiona una interrupción de trampa de tal forma que al ejecutar una instrucción se genera la interrupción 1, por esta razón se le llama trampa de paso a paso. Cuando TF = 0 la ejecución del programa es normal. Las instrucciones: STI: carga un ‘1’ en IF por lo que habilita la terminal INTR del µP (activa interrupciones). CLI: desactiva interrupciones del hardware (terminal INTR del µP). Orden de prioridad Las interrupciones tienen un orden de prioridad, de forma que si ocurren dos de forma simultánea es atendida la de prioridad más alta. El orden en que se atienden es el siguiente: 1º: Interrupciones (o excepciones) del procesador.

2º: Interrupciones software. 3º: Interrupciones de hardware (o periféricos) no enmascarables. 4º: Interrupciones hardware (o periféricos) enmascarables.

Interrupciones internas o excepciones: Las genera la propia CPU cuando se produce una situación anormal o cuando llega el caso. Por desgracia, IBM se saltó olímpicamente la especificación de Intel que reserva las interrupciones 0-31 para el procesador.

o INT 0: error de división, generada automáticamente cuando el cociente no cabe en el registro o el divisor es cero. Sólo puede ser generada mediante DIV o IDIV. Hay una sutil diferencia de comportamiento ante esta interrupción según el tipo de procesador: el 8088/8086 y los NEC V20 y V30 almacenan en la pila, como cabría esperar, la dirección de la instrucción que sigue a la que causó la excepción. Sin embargo, el 286 y superiores almacenan la dirección del DIV o IDIV que causa la excepción.

o INT 1: paso a paso, se produce tras cada instrucción cuando el procesador está en modo traza (utilizada en depuración de programas).

o INT 2: interrupción no enmascarable, tiene prioridad absoluta y se produce incluso aunque estén inhibidas las interrupciones (con CLI) para indicar un hecho muy urgente (fallo en la alimentación o error de paridad en la memoria).

o INT 3: utilizada para poner puntos de ruptura en la depuración de programas, debido a que es una instrucción de un solo byte muy cómoda de utilizar.

o INT 4: desbordamiento, se dispara cuando se ejecuta un INTO y había desbordamiento.

o INT 5: rango excedido en la instrucción BOUND (sólo 286 y superiores). Ha sido incorrectamente empleada por IBM para volcar la pantalla por impresora.

o INT 6: código de operación inválido (sólo a partir del 286). Se produce al ejecutar una instrucción indefinida, en la pila se almacena el CS:IP de la instrucción ilegal.

o INT 7: dispositivo no disponible (sólo a partir del 286).

Interrupciones hardware:

Son las generadas por la circuitería del ordenador en respuesta a algún evento. Las más importantes son:

o INT 8: Se produce con una frecuencia periódica determinada por el canal 0 del chip temporizador 8253/8254 (en la práctica, unas 18,2 veces por segundo). Como desde esta interrupción se invoca a su vez a INT 1Ch -porque así lo dispuso IBM-, es posible ligar un proceso a INT 1Ch para que se ejecute periódicamente.

o INT 9: generada al pulsar o soltar una tecla.

o INT 0Ah, 0Bh, 0Ch, 0Dh, 0Eh, 0Fh: Puertos serie, impresora y controladores de disquete.

o INT 70h, 71h, 72h, 73h, 74h, 75h, 76h, 77h: Generadas en los AT y máquinas superiores por el segundo chip controlador de interrupciones.

Interrupciones de periféricos El µP posee 2 terminales de entrada para interrupciones de periféricos:

- interrupción no enmascaradle NMI y - Solicitud de interrupción INTR

Cuando se activa la terminal NMI ocurre la interrupción 2 La terminal INTR se debe decodificar externamente para seleccionar un vector. Es posible escoger cualquier vector de interrupción para la terminal INTR el cual generalmente se establezca como interrupción entre ZON y FFN.

- INTA: Es una terminal del µP pero es de salida y se utiliza como respuesta a la entrada INTR.

Instrucciones para el control de µP Son instrucciones que comúnmente se emplean en el control de hardware.

- Control de bit de la bandera de acarreo (CF) mediante las instrucciones STC (activa acarreo) y CLC (desactiva acarreo) y CMC (complemento del acarreo).

- WAIT: Esta instrucción monitorea la terminal BUSY de los µP 286 y 386 y la terminal TEST de los µP 8086 y 8088.

Al ejecutar la instrucción WAIT y la terminal BUSY = 0 no ocurre nada y se ejecuta la siguiente instrucción normalmente pero si BUSY = 1 el µP espera hasta que la terminal BUSY regresa a 0. BUSY es una terminal de entrada al µP y comúnmente se conecta a la terminal BUSY del coprocesador numérico 8087-80387.

TABLA DE INTERRUPCIONES DEL SISTEMA

INT 00: División por cero INT 01: Ejecución paso a paso INT 02: No Enmascarable (NMI) INT 03: Puntos de ruptura INT 04: Desbordamiento (INTO) INT 05: Volcar pantalla por impresora (BIOS) INT 06: Código de operación incorrecto INT 07: Reservada INT 08: IRQ 0: Contador de hora del sistema (BIOS) INT 09: IRQ 1: Interrupción de teclado (BIOS) INT 0A: IRQ 2: canal E/S, segundo 8259 del AT INT 0B: IRQ 3: COM2 INT 0C: IRQ 4: COM1 INT 0D: IRQ 5: disco duro XT, LPT2 en AT, retrazo vertical PCjr INT 0E: IRQ 6: Controlador del disquete INT 0F: IRQ 7: LPT1 INT 10: Servicios de vídeo (BIOS) INT 11: Listado del equipo (BIOS) INT 12: Tamaño de memoria (BIOS) INT 13: Servicios de disco (BIOS) INT 14: Comunicaciones en serie (BIOS) INT 15: Servicios del sistema (BIOS) INT 16: Servicios de teclado (BIOS) INT 17: Servicios de impresora (BIOS) INT 18: IBM Basic (ROM del BASIC) INT 19: Arranque del sistema (BIOS) INT 1A: Fecha/hora del sistema

INT 1B: Acción de CTRL-BREAK (BIOS) INT 1C: Proceso periódico del usuario (Usuario) INT 1D: Parámetros de vídeo (BIOS) INT 1E: Parámetros del disquete (BIOS) INT 1F: Tabla de caracteres gráficos (BIOS) INT 20: Fin de programa (DOS) INT 21: Servicio del sistema operativo (DOS) INT 22: Dirección de terminación (DOS) INT 23: DOS CTRL-BREAK (DOS) INT 24: Manipulador de errores críticos (DOS) INT 25: Lectura absoluta de disco (DOS) INT 26: Escritura absoluta en disco (DOS) INT 27: Terminar permaneciendo residente (DOS) INT 28: DOS Idle (programas residentes que usan funciones DOS) INT 29: DOS TTY (impresión en pantalla) INT 2A: Red local MS net INT 2B-2D: Uso interno del DOS INT 2E: Procesos Batch (DOS) INT 2F: Multiplex (DOS) INT 30: Compatibilidad CP/M-80 (xx:YYyy en JMP XXxx:YYyy) INT 31: Compatibilidad CP/M-80 (XX en JMP XXxx:YYyy) INT 32: Reservada INT 33: Controlador del ratón INT 34-3F: Reservadas INT 40: Interrupción de disquete (BIOS) INT 41: Parámetros del disco duro 1 (BIOS) INT 42: Apunta a la INT 10h original del BIOS si existe VGA INT 43: Caracteres gráficos EGA (BIOS) INT 44-45: Reservadas INT 46: Parámetros del disco duro 2 (BIOS) INT 47-49: Reservadas INT 4A: Alarma del usuario INT 4B-5F: Reservadas INT 60-66: Para uso de los programas INT 67: Interrupción de EMS (controlador EMS) INT 68-6F: Reservadas INT 70: IRQ 8: Reloj de tiempo real AT (2º chip 8259-AT) INT 71: IRQ 9: IRQ 2 redireccionada (2º chip 8259-AT) INT 72: IRQ 10: reservada (2º chip 8259-AT)

INT 73: IRQ 11: reservada (2º chip 8259-AT) INT 74: IRQ 12: interrupción de ratón IBM (2º chip 8259-AT) INT 75: IRQ 13: error de coprocesador matemático (2º chip 8259-AT) INT 76: IRQ 14: controlador disco fijo (2º chip 8259-AT) INT 77: IRQ 15: reservada (2º chip 8259-AT) INT 78-7F: Reservadas INT 80-85: Reservadas para el Basic INT 86-F0: Usadas por el Basic INT F1-FF: Para uso de los programas

Plan de memoria de IBM

FFFFFFFF

FFFFFF

3.98 Gb Memoria extendía (386)

Memoria extendida

110000

14.9 Mb Memoria extendida (286/386) 64 Kb HMA (286/386) para el nuvleo del DOS (AT) Memoria alta

(64 Kb) 100000 - zona mas alta accesible por el DOS -

F0000

64 Kb ROM BIOS (y/o memoria superior 386)

E0000 64 Kb EMS (PC/XT/AT) (o memoria superior 386)

D0000

64 Kb EMS (PC/XT/AT) (o memoria superior 386)

C0000

64 Kb extensiones de ROM (y/o memoria superior 386

Memoria Superior (máximo 384 Kb)

A0000

128 Kb Memoria máxima de video direccionable

Memoria Convencional (640 Kb)

00600

638.5 Kb RAM de usuario (y núcleo del DOS PC/XT)

00500

Área de datos del DOS y del BASIS

Variables de la BIOS y de las extensiones de ROM 00400

00000 Vectores de interrupción