P. 1
INTERRUPCIONES ENSAMBLADOR

INTERRUPCIONES ENSAMBLADOR

|Views: 2.861|Likes:
Publicado porAngel Liborio

More info:

Published by: Angel Liborio on Apr 28, 2011
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as DOCX, PDF, TXT or read online from Scribd
See more
See less

07/31/2013

pdf

text

original

11.1.

Interrupciones
Las interrupciones son un mecanismo por el que un dispositivo externo puede provocar que el procesador interrumpa momentáneamente la ejecución del programa para atender su petición y luego continuar con el programa desde el punto en que lo había dejado. Pe ro el procesador 8086 amplía este concepto y permite que un programa pueda generar una interrupción en cualquier momento. A este tipo de interrupciones se las conoce como interrupciones sofware para diferenciarlas de las interrupciones hardware, generadas por dispositivos externos al procesador. Existen, no obstante, de 8 a 15 interrupciones que no se llaman de la misma forma que las interrupciones de software, sino mediante el controlador de interrupciones, como interrupciones hardware.

11.1.1. Polling versus Interrupciones
Ambos son protocolos de comunicación entre dispositivos de E/S y el microprocesador. En capítulos posteriores veremos una técnica más llamada DMA.

11.1.1.1. Polling
También llamada técnica de las consultas sucesivas. Es la más simple de las dos. Para ella los dispositivos se conectan al bus de direcciones, al de datos y al de control. El procesador se encarga de ir consultando a los dispositivos conectados a él si necesitan atención o no. En caso negativo se pasa a consultar al siguiente. En cuanto uno conteste que sí, se empezará la transmisión. Esto requiere de un programa llamado bucle de consulta que compruebe un bit del dispositivo de su interfaz. Con este método se sabe exactamente cuándo se pregunta a un dispositivo, cuándo se comun ica con él y cuánto se tarda en darle servicio. Es una operación sincronizada con el programa. Se consigue así establecer fácilmente unas prioridades, consultando antes al dispositivo de mayor prioridad. Por otro lado, este sistema representa una carga par a el programa y responde con excesiva lentitud a la llamada del dispositivo, pues hasta que el programa no consulte no se establece la comunicación.

11.1.1.2. Interrupciones

Su filosofía es contraria a la anterior, consiste en que son los dispositivos de E/S los que solicitan atención al procesador, quien al recibirla, puede aceptarla o no. Puede ser que el proceso que se esté efectuando en ese momento requiera la prohibición de esa interrupción, se habla entonces de enmascaramiento de interrupciones. Si no están enmascaradas las interrupciones se suspende el programa que se estaba ejecutando y el control se transfiere a una rutina de atención al dispositivo en cuestión, que una vez terminado, vuelve a ejecutar el proceso interrumpido por donde se suspendió. Para realizar este proceso, la unidad de entrada y salida (su inferfaz) tiene que enviar lo que se llama un vector (la clave que le identifica), normalmente por el bus de da tos.

11.1.1.3. Conclusión
El método polling es más sencillo que el interruptivo, pero más lento. Imaginemos que estamos escribiendo en el ordenador a razón de una pulsación por segundo. El microprocesador debe interrumpir su ejecución cada segundo para recoger esta información. Sin embargo, es posible que a veces escribamos más rápido y otras veces más lento, por lo que el procesador debería mirar más a menudo si ha habido pulsación de tecla. En muchas ocasiones volverá de vacío. Por tanto, vemos que este s istema desperdicia mucho tiempo. Por el contrario, en el sistema interruptivo el microprocesador no deja de hacer sus tareas y, cuando le llega una petición de atención, deja momentáneamente su proceso para atender esta petición (siempre que el proceso que estuviese haciendo no fuese delicado).

11.1.2. Interrupciones internas o excepciones
Las genera la propia CPU cuando se produce una situación anormal o cuando llega su momento. Intel definió del 0 al 20h para uso interno de la CPU, desgraciadamente IBM se saltó esta especificación y redefinió del 0 al 1Fh para su propio uso, por lo que existen definiciones duplicadas en las tablas.
y

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. El 8088/8086 guardan en la pila la sentencia siguiente a la que causó la excepción, mientras que el 286

y INT 6: Código de operación inválido (sólo a aprtir del 186). y INT 4: Desbordamiento.y superiores guardan la sentencia que la generó. estén prioridad inhibidas indicar interrupciones hecho muy urgente. Se produce tras cada instrucción cuando el procesador está en modo traza (utilizado para la depuración de programas). Se dispara cuando se ejecuta un INTO y había desbordamiento. En la pila se guarda el CS:IP de la instrucción ilegal. y INT 5: rango excedido en Ha la pantalla la instrucción BOUND (sólo 186 y superiores). y INT 3: Utilizada para poner puntos de ruptura en la depuración de programas. Si no hay desbordamiento INTO equivale a NOP. Se produce al ejecutar una instrucción indefinida. y INT 1: Paso a paso. y INT 7: Dispositivo no disponible (sólo a partir del 286). . y INT absoluta aunque 2: y Interrupción Tiene produce para se no incluso las un enmascarable. para volcar sido por incorrectamente empleada por IBM impresora.

3. Generada al pulsar o soltar una tecla. Retrazo vertical en EGA/VGA Generados en los AT y superiores por el segundo chip controlador de interrupciones . Interrupciones hardware (IRQs) Acrónimo de Interrupt ReQuest o Petición de Interrupción. Hay un pulso cada 55 milisegundos. Es la denominación habitual de las interrupciones hardware.2 veces por segundo. Segmento no presente (a partir del 286) y INT C: Excepción de pila (a partir del 286) y INT D: Excepción de protección general (a partir del 286) y INT E: Fallo de página (a partir del 286) y y INT F: Reservado INT 10: Error de coprocesador ( a partir del 286) 11.1.y INT 8: Excepción de doble fallo (a partir del 286) y INT 9: Desbordamiento del coprocesador del (a segmento partir del 286) y INT A: Segmento de estado de tarea inválida (a partir del 286) y INT B. En orden de prioridad: IRQ Interrupción Función 0 1 2 8 9 8 9 A 70 71 Se produce con una frecuencia de 18. generadas por la circuitería del ordenador en respuesta a algún evento.

de esta manera estandarizamos nuestro código. El número de interrupción generada por el 8259 se calcula como un número base de 8 al que se le suma un número entre 0 y 7 correspondiente a la línea de interrupción. Cuando se enciende la computadora "arranque en frío" el procesador ingresa un estado de restablecer. por lo que las ocho distintas IRQs generan interrupciones entre 8 y 15. cada uno con sus propias identificaciones y formas diferentes de programarlas. A partir de aquí. que es el que está conectado a la pata de petición de interrupción del procesador y es el que genera las señales de interrupción en la forma en que las espera éste. Localización La BIOS se encuentra en la memoria ROM. 11.Interrupciones Hardware En el PC. 11.4. los dispositivos susceptibles de provocar interrupciones están conectados al chip 8259. realiza una verificación de la paridad de memoria y coloca FFFFh en el registro CS y cero en el IP. por lo que la primera instrucción a ejecutar está en FFFF:0000 que es el punto de entrada de la BIOS. pone todas las localidades de la mem oria en cero. Interrupciones software Acceder directamente a cada uno de los elementos del ordenador sería terrible.1. Este circuito soporta ocho líneas de entrada de petición de interrupción (IRQ0 A IRQ7). Para allanar este problema existe la BIOS que es un extenso conjunto de rutinas de entrada/salida que podemos usar para comunicarnos con el ordenador sin tener en cuenta el modelo de sus com ponentes.10 11 12 13 14 15 3 4 5 6 7 72 73 74 75 76 77 B C D E F Se requiere servicio COM2 o COM4 Se requiere servicio COM1 o COM3 Disco duro o datos requeridos por LPT2 Servicio de disquete requerido Datos requeridos por LPT1 Tabla 11-01 . la BIOS verifica los . además de que existen multitud de modelos diferentes.1.1.4.

COM -u 100. la primera del DOS es 20h para la terminación del programa. Puesto que son punteros lejanos (4 bytes) y su posición se corresponde con el número de la interrupci ón en la forma: para la interrupción i. que está justo a continuación de la última interrupción MS -DOS.diferentes puertos para identificar e inicializar dispositivos que están conectados. A continuación comprueba si existe un sistema operativo en el disco para acceder a su primer sector que contiene el cargador de arranque que es un sistema operativo temporal que recoge el control de la BIOS para cargar en memoria el sistema operativo final. 7C 10 A7 00 MOV MOV INT MOV INT DX. que comienza a partir de la última de la BIOS. 10B 0CC8:0100 BA0C01 0CC8:0103 B409 0CC8:0105 CD21 0CC8:0107 B8004C 0CC8:010A CD21 -r ES ES 0CC8 :0 -d ES:84 l4 0000:0080 |.09 21 AX. Una vez que se ha cargado el MS -DOS en memoria tenemos relleno el Vector de Interrupciones que comprende las localidades de memoria 0000:0000 ± 0000:03FF donde se hayan todas las interrupciones de la BIOS (desde 00h hasta 1Fh) y del DOS (desde 20h hasta 3FFh)..4. Ejemplo / traceo Usaremos el programa dosCM3 para rastrear el uso de la interrupción INT 21h: F:\Alfonso\Codigos\Cap8>debug DOSCM3. Así. por ejemplo.. que es una secuencia de punteros lejanos (4 bytes) a las rutinas de interrupción de la BIOS. para INT 21h buscaremos en 21h * 4h = 84h.4C00 21 .010C AH. Existe además un área de datos reservado para la BIOS de 256 bytes (100h) a partir de la posición 0040:0000 con abundante inform ación del sistema. 11. Obsérvese que 0040:0000h equivale a 0000:0400h.1.2. la posición i*4. es decir en 0000:0084. y a continuación define el "Vector de Interrupciones" a partir de la localización 0000:0000 de la memoria.

Proceso de la interrupción Las interrupciones pueden ser activadas directamente por el ensamblador invocando el número de la interrupción a través de la instrucción INT y el número de función deseada pasada generalmente en el registro AH. 11. a continuación anulamos el valor de ES para poder acceder al área 0000:0084 del vector de Interrupciones donde se guarda el puntero al código de la interrupción 21h (obsérvese que 21h * 4h = 8 4h) donde obtenemos el valor "7C 10 A7 00" en formato little endian.-p AX=0000 DI=0000 DS=0CC8 PO NC BX=0000 ES=0000 CX=002D SS=0CC8 DX=010C CS=0CC8 SP=FFFE IP=0103 BP=0000 SI=0000 NV UP EI PL NZ NA 0CC8:0103 B409 -p MOV AH. A continuación salimos. que es justamente el valor que obtuvimos en ES:84 traducido del little endian. Cuando se ejecuta esta instrucción el procesador: .4. Seguidamente ejecutamos el código hasta llegar a "INT 21" donde ejecutamos con "t" para tracearla y comprobamos que saltamos a la posición 00A7:107C.09 AX=0900 DI=0000 DS=0CC8 PO NC BX=0000 ES=0000 CX=002D SS=0CC8 DX=010C CS=0CC8 21 SP=FFFE IP=0105 BP=0000 SI=0000 NV UP EI PL NZ NA 0CC8:0105 CD21 -t INT AX=0900 DI=0000 DS=0CC8 PO NC BX=0000 ES=0000 CX=002D SS=0CC8 DX=010C CS=00A7 SP=FFF8 IP=107C BP=0000 SI=0000 NV UP DI PL NZ NA 00A7:107C 90 -q NOP En primer lugar desensamblamos el código para tenerlo presente.1.3.

pero las interrupciones internas o excepciones sólo guardan la CS:IP de la instrucción causante. en Al este igual orden que (la con instrucción actual es la siguiente a la sentencia INT). Borra la bandera de atrape (TF) y activa la bandera de interrupciones (IF) 3. pues devuelven la instrucción siguiente a la división.1. CS y de banderas. Hemos visto que todas las interrupciones guardan en la pila el registro de banderas y el CS:IP de la siguiente instrucciones. Guarda el registro de banderas en la pila. 2. "CALL" esto asegura que el control vuelve a la siguiente posición lógica en el programa. llegando a la deseada mediante la fórmula 0000:i*4 donde i es el número de interrupción. como se especificó en la Tabla del Vector de Interrupciones. Recupera de la pila los valores de los registros IP. Ejecuta el código de la rutina de interrupciones hasta encontrarse una instrucción "IRET". 5. 4. Salta a la dirección de la rutina de interrupciones. Mira hacia la dirección de la rutina de interrupción en la Tabla del Vector de Interrupciones (en la posición 0000:0000). las excepciones de división del 8086/88 son diferentes.1. 11. 6.5. el segmento de código actual (CS) y el puntero de instrucciones actual (IP). Además.Tabla de interrupciones del sistema INT Situación Nombre .

00h 01h 02h 03h 04h 05h 06h 07h 08h 09h 0Ah 0Bh 0Ch 0Dh 0Eh 0Fh 10h 11h 12h 13h 14h 15h 16h 17h 18h 19h 1Ah 1Bh 1Ch 1Dh 1Eh 1Fh 20h 21h 22h CPU CPU CPU CPU CPU BIOS CPU CPU IRQ0 IRQ1 IRQ2 IRQ3 IRQ4 IRQ5 IRQ6 IRQ7 BIOS BIOS BIOS BIOS BIOS BIOS BIOS BIOS BIOS BIOS BIOS BIOS BIOS BIOS BIOS BIOS DOS DOS DOS División por cero Ejecución paso a paso No enmascarable (NMI) Puntos de ruptura Desbordamiento (INTO) Volcar pantalla por impresora Código de operación incorrecto Reservada IRQ 0: Contador de hora del sistema IRQ 1: Interrupción de teclado IRQ 2: canal E/S. LPT2 en AT. segundo 8259 del AT IRQ 3: COM2 IRQ 4: COM 1 IRQ 5: disco duro XT. retrazo vertical PCjr IRQ 6: Controlador del disquete IRQ 7: LPT1 Servicios de vídeo Listado de equipos Tamaño de memoria Servicios de disco Comunicaciones en serie Servicios del sistema Servicios de teclado Servicios de impresora IBM Basic (ROM del Basic) Arranque del sistema Fecha/hora del sistema Acción de CTRL-Break Proceso periódico del usuario Dirección de la tabla de parámetros de vídeo Dirección de la tabla de parámetros de disquete Dirección de caracteres gráficos Fin de programa Llamar función DOS Dirección de terminación .

23h 24h 25h 26h 27h 28h 29h 2Ah DOS DOS DOS DOS DOS DOS DOS DOS Dirección de la rutina CTRL-BREAK del DOS Dirección manipulador de errores críticos Lectura absoluta de disco Lectura absoluta de disco Finalización de programa residente El DOS está desocupado DOS TTY (impresión en pantalla) Red local MS net Uso interno del DOS Procesos Batch Multiplex Compatibilidad CP/M-80 (xx:YYyy en JMP Xxxx:YYhh) Compatibilidad CP/M-80 (XX en JMP Xxx:YYyy) Reservada Controlador del ratón Reservadas 2Bh-2Dh DOS 2Eh 2Fh 30h 31h 32h 33h 34h-3Fh 40h 41h 42h 43h BIOS BIOS BIOS BIOS DOS DOS CPM DPMI Interrupción de disquete Parámetros del disco duro 1 Apunta a la INT 10h original de la BIOS si existe VGA Caracteres gráficos EGA Reservadas Parámetros del disco duro 2 Reservadas Alarma del usuario Reservadas Para uso de los programas 44h-45h BIOS 46h BIOS 47h-49h BIOS 4Ah BIOS 4Bh-5Fh BIOS 60h-66h 67h 68h-6Fh 70h 71h 72h 73h 74h 75h 76h IRQ8 IRQ9 IRQ10 IRQ11 IRQ12 IRQ13 IRQ14 EMS Interrupción de EMS (controlador EMS) Reservadas IRQ 8: Reloj de tiempo real AT IRQ 9: IRQ 2 redireccionada IRQ 10: reservada IRQ 11: reservada IRQ 12: Interrupción de ratón IBM IRQ 13: error de coprocesador matemático IRQ 14: controlador de disco fijo .

de nosotros depende hacer el resto con un "PUSH" de todos los registros y un "POP" de éstos al terminar la ISR antes del "IRET". hay veces que es necesario deshabilitar esta posibilidad . Ya hemos visto que básicamente. Es decir. Veamos algunas características y consejos interesantes de las ISR. y redireccionamos la ejecución a la rutina de interrupción pasada en "INT" que termina cuando encuentra un "IRET" que hace un "POP" de la pila del IP.77h 78h-7Fh 80h-85h IRQ15 IRQ 15: reservada Reservadas Reservadas para el Basic Usadas por el BASIC Para uso de los programas Tabla 11-02 . También hemos dicho que la dirección de la rutina a llamar con un "INT" se encuentra en la tabla de vectores de interrupción localizada a partir de 0000:0000h.6. por ejemplo.1. Preservar contenido de registros Según la filosofía que hemos comentado al principo de este capítulo. el registro de banderas ya se hace de forma automática. el funcionamiento es muy similar al de una subrutina llamada con un "CALL" y terminada con un "RET".1. AX Y la interrupción que tratamos se ejecuta entre ambas. 11. 500 ADD BX. el resultado puede ser muy grave. Es la rutina para cada tipo de interrupción. Por tanto. cuando ejecutamos un "INT" metemos en la pila el registro de banderas.1.2. las interrupciones pueden ser ejecutadas en cualquier momento. ISRs Acrónimo de Interruption Service Routine o Rutina de Servicio a la Interrupción.6.1. CS y del registro de banderas. debido a que las interrupc iones pueden ser ejecutadas en cualquier momento.6. de tal modo que modifica el contenido del registro AX. Deshabilitar ejecución de interrupciones De nuevo. el CS y el IP. supongamos que tenemos el siguiente código: MOV AX. es conveniente preservar el contenido de todos los registros en el código de nuestra ISR.Tabla de interrupciones del sistema 86h-F0h DOS F1h-FFh 11. 11. que apuntan a la siguiente instrucción.

La bandera IF indica si las interrupciones están activadas o desa ctivadas con un 1 y un 0 respectivamente. 9000h CLI MOV SS. En el caso de modificar manualmente el contenido del vector de interrupciones.6. por si se ejecuta alguna antes de completar este proceso. por lo que una opción buena sería modificar la doble palabr a de un solo golpe con "REP MOVS" con lo que no damos oportunidad a ninguna interrupción a actuar en medio. Una forma de evitar esto es desactivando temporalmente las interrupciones: MOV AX. Habilitamos interrupciones . AX". 9000h MOV SS. Reservar suficiente espacio de pila . Deshabilitamos interrupciones De esta forma nos aseguramos que en la parte crítica de nuestro código no ocurre ninguna interrupción. Sin embargo. el resul tado puede ser impredecible. aunque las tengamos deshabilitadas con CLI. puesto que sólo hemos cambiado su dirección a medias.1. 3000h Pero ocurre una interrupción justo de pués de "MOV SS. Esto se hace con STI y CLI respectivamente.para asegurarnos de que no se va a alterar cierto sector crítico de nuestro código. 11. Obsérvese que si hemos cambiado sólo una palabra de las dos y una salta una interrupción en medio que hace uso de la que estamos cambiando. con lo que el resultado puede ser desastroso. sería necesario deshabilitar éstas. Supongamos que queremos definir dentro de nuestra ISR una pila propia en otro segmento: MOV AX. pero ya hemos visto que esto no siempre es suficiente puesto que un CLI no inhibe una interrupción no enmascarable. existen ciertas situaciones críticas en las que ocurren excepciones. diferente al esperado en la ISR que ha tomado el control. Es el caso. AX MOV SP. por ejemplo de fallos importantes de hardware. 3000h STI . seguramente. AX MOV SP.3. Ahora el registro de pila SS contiene un valor.

y Reemplaza la dirección de la antigua rutina en la Tabla del Vector de Interrupciones con la dirección de la nueva rutina. puesto que esta última se encargará de hacerlo. . que es recogido por el 8259. y Guardamos la dirección de la ISR que queremos cambiar.Aunque para nuestro código no necesitemos mucho espacio de pila. Imagínate que usamos variables. he interceptado la 1Ch del reloj en el Tetris y me daba problemas algún otro procedimiento. no sólo en la ISR. y La nueva rutina con una debería ser siempre definida como LEJANA y terminar instrucción "IRET" en lugar de "RET". para lo cuál debe cumplir: y Provee una nueva ISR para manejar la interrupción. Gestión de interrupciones Vamos a ver algunos ejemplos de creación de interrupciones y solapamiento de otras. hay que procurar preservar los registros de segmento. interrupciones que 11.7. podremos tener resultados insospechados. Esto se hace enviando el valor 20h al puerto 20h. sino en el resto de procedimientos que usemos fuera de ella. No es necesario hacer esto. En mi caso. sí será necesario reservar el suficiente para las posibles pudieran surgir durante su ejecución.1. en el caso de que nuestra ISR pase el control a la antigua ISR. Es necesario informar al controlador de interrupciones que ya ha sido atendida una IRQ inmediatamente antes de retornar de la rutina de servicio a la interrupción con IRET. MUY IMPORTANTE Cuando se intercepta una interrupción. Se puede reemplazar una rutina de interrupción con nuestro código. con nuestra propia ISR. sin embargo. especialmente con las interrupciones del reloj. Tuve que poner en cada procedimiento explícitamente qué valían DS y ES. pero nuestra rutina ya no sabe qué vale DS o ES.

1. sólo disponemos para los programas del C0h al FFh. Del 00h al 2Fh BFh están reservados. más estándares y menos dependientes del tipo de hardware instalado. Lo que normalmente haremos será modificar temporalmente una ISR por una nuestra para cumplir con algún tipo de gestión. Es un método para verificar la presencia de un TSR y comunicarse con él. Extra AL = nº interrupción (0 a 255) DS:DX = dirección nueva ISR Descripción Establece una nueva ISR para el número de interrupción indicado en AL Devuelve en ES:BX la dirección 21h 35h AL = nº interrupción (0 a 255) de la ISR correspondiente al número de interrupción pasado en AL En AH ponemos el identificador del programa que engancha con la interrupción. deberíamos restaurar el método original. volvemos a poner en la Tabla del Vector dirección De Interrupciones de la la ISR guardada cambiada original. 21h 25h Tabla 11-03 .y Antes de terminar el programa.Funciones para gestión de Interrupciones . AL es el código de función A esta interrupción se la llama multiplex. Int AH Inf. por ejemplo. 11. que si utilizamos.1. El uso de interrupciones nos ayuda a la creación de programas haciéndolos más pequeños y fáciles de entender. Una vez termi nada. Sin embargo.7. no es necesario volver a poner el valor original. puesto que son la BIOS y el DOS los encargados de proporcionarnos estos servicios. Asimismo quizás queramos modificar alguna ISR indefinidamente para establecer un nuevo controlador de dispositivos. existen algunas localidades en la Tabla de Vectores de Interrupciones reservadas para las interrupciones del usuario. Interrupciones para gestión de interrupciones El MS-DOS nos proporciona ciertas herramientas que nos facilitan la gestión de interrupciones. de modo que nuestra interrupción estará disponible durante toda la vida de la sesión del MS-DOS. no tenemos por qué hacer esto forzosamente.

0 MOV ES.2. Una vez que nuestra ISR haya cumplido su cometido deberemos resta urar la dirección de la antigua ISR que tenemos guardada en su casilla de la Tabla del Vector de Interrupciones. 2 . AX LEA DI. 0 MOV DS. AX LEA SI. la interrupción 21h también puede ser interceptada. Este es el método recomendable para la gestión de interrupciones. oldISR MOV CX. Con la función 25h establecemos la nueva ISR que sustituirá a la anterior. Dirección en la Tabla de Vectores a Equivalente a la función 35h PUSH DS PUSH ES MOV SI. Sin embargo. En este caso tan extraordinario podríamos vernos obligados a hacerlo a mano. es el uso de las interrupciones que hemos visto arriba. 2 CLI REP MOVSW STI POP ES . Métodos para la gestión de interrupciones El método deseado. Vector*4 guardar PUSH DS POP ES MOV AX. puesto que es el más sencilloy el estándar porque nos lo ofrece el MS-DOS. básicamente lo que hace es meter en aquella casilla de la Tabla del Vector de Interrupciones la dirección de nuestra ISR. DS: SI -> newISR .Con la función 35h obtenemos de la Tabla de Vectores de Interrupción la dirección de la ISR que queremos modificar. Esta función la guardamos. Desactivamos interrupciones . newISR MOV CX. Vector*4 cambiar MOV AX. con lo que el primer método podría no funcionar.7. Equivalente a la función 25h PUSH ES MOV DI.1. 11. Dirección en la Tabla de Vectores a .

pero si tienes un XP seguramente no te funcionarán algunos. Int 4h IntCM1 IntCF1 IntCN1 Resultado en pantalla Código [bin] Código Código [bin] [bin] C:\Trabajo\AOE\Codigos\Cap11>IntCF1 Mensaje de desbordamiento desde mi ISR Source 11-01 . reponemos la dirección de la ISR original de la Int 4h. A continuación comprobamos si funciona. La siguiente multiplicación sí desborda. Int 21h IntCM2 IntCF2 IntCN2 Resultado en pantalla Código Código Código C:\Trabajo\AOE\Codigos\Cap11>IntCM2 Instalada nueva Int 21h [bin] [bin] [bin] alfonso Has pulsado 8 teclas . Obsérvese que la nueva ISR termina con un "IRET".1. por lo que el "INTO" pasa a "newISR" que muestra el mensaje. Finamente.1. que guardamos en la variable "vector" (little endian).Intercepción de la interrupción 4 Con la función 35h de Int 21h la dirección de la ISR de la interrupción 4h en ES:BX. por lo que el "INTO" equivale a un "NOP".8.8. Con la función 25h de Int 21h modificamos en la Tabla de Vectores de Interrupción la dirección de la ISR de la Int 4h por nuestra nueva rutina en "newISR".2.1.CLI REP MOVSW STI POP ES POP DS . Primero hacemos una multiplicación que no desborda. Desactivamos interrupciones 11. 11. Y es que WXP no parece tratarlos muy bien. Importante Es más que conveniente ejecutar estos ejemplos desde la ventana de comandos de Windows. en este caso habría que echar mano de una plataforma como DOSBox.8. especialmente los programas residentes. 11.1. Si posees un W95 o W98 te irán todos bien. Ejemplos Veremos algunos códigos de ejemplo de intercepción de interrupciones.

A continuación incrementamos el contador. Tenemos el código completo en IntC?2b. Obsérvese que nuestra ISR la podemos construir de otra manera quizás más limpia y elegante.Source 11-02 . No necesitamos un "PUSHF" puesto que esto ya lo hizo la "INT" que llamó a nuestra ISR.asm2. por lo que vamos viendo lo que vamos escribiendo. to old BIOS INT9 handler . entrada . cuenta las teclas pulsadas hasta intro . En resumen. Activa bandera de . Obsérvese que cuando entramos en una ISR sólo conocemos el valor del registro "CS". Esta función vuelca por pantalla la tecla pulsada. Nuestra nueva ISR para Int 21h activa las interrupciones con "STI". el código del procedimiento "NuevaInt21h" quedaría como sigue: NuevaInt21h PROC FAR . Destruye : Ninguna STI interrupciones INC JMP CLI NuevaInt21h ENDP BYTE PTR [NumTeclas] [CS:OldInt21h] . salida : NumTeclas : NumTeclas .Intercepción de la interrupción 21h Primero guardamos la dirección de la ISR original en la variable "OldInt21h" que se encuentra dentro de la rutina "NuevaInt21h" e instalamos la nueva ISR para la interrupción 21h correspondiente al procedimiento NuevaInt21h. con lo que finalmente tendremos la cuenta de teclas pulsadas. puesto que eso ya lo hace la antigua ISR. En un bucle vamos recogiendo la s teclas pulsadas con la función 1h de Int 21h y terminamos al pulsar la tecla retorno. . la cuál tampoco necesitamos terminar con una "IRET". Para terminar restauramos en la Tabla de Vectores de Interrupción la dirección de la ISR original de la Int 21h. podríamos hace r la llamada a la antigua ISR mediante un simple "JMP". Obsérvese que la tecla retorno también cuenta. guarda el registro de banderas con "PUSHF" (puesto que el último POP de IRET es "POPF") y hace un "CALL" lejano (DB 9Ah) a la ISR original de la Int 21h para que se encargue de todo el trabajo duro. que en un archivo "COM" coincide con "DS". Esto se ejecuta cada vez que pulsamos una tecla. Puesto que hacemos una llamada a la antigua ISR de la Int 21h y ésta finaliza con un "IRET" y el acceso a nuestra ISR se efectúa mediante una "INT". Propósito: Nueva ISR para INT 21h. Código de la tecla pulsada La variable "OldInt21h" la hemos situado en la zona de datos.

Int 9h IntCM3 IntCF3 IntCN3 Resultado en pantalla Código Código Código C:\Trabajo\AOE\Codigos\Cap11>IntCM3 Instalada nueva Int 9h [bin] [bin] [bin] Has pulsado 0 teclas Source 11-04 .1.Intercepción de la interrupción 21h 11. IntCM4 IntCF4 IntCN4 Resultado en pantalla Código [bin] Código Código [bin] [bin] Source 11-05 . Int 8h Vamos a ver en este ejemplo cómo interceptamos la IRQ0 que se produce 18. que es la que interceptamos en este ejemplo. en cuyo caso salimos. 11. en nuestra ISR distinguimos esta posibilidad para incrementar el contador sólo cuando pulsamos una tecla.8.4.3.Intercepción de la interrupción 9 El mecanismo es igual al programa anterior sólo que en el bucle usamos el puerto 60h para recoger la tecla pulsada y la comparamos con el código scan "1Ch" para comprobar si hemos pulsado la tecla retorno. cuyas agujas se mueven cada dos segundos. Por tanto.2 veces por segundo (se genera un pulso cada 55 milisegundos) y que gestiona el tiempo. Al pulsar o soltar una tecla se activa la IRQ1 correspondiente a la interrupción 9h.IntCM2b IntCF2b IntCN2b Resultado en pantalla Código Código Código C:\Trabajo\AOE\Codigos\Cap11>IntCN2b Instalada nueva Int 21h [bin] [bin] [bin] alfonso Has pulsado 8 teclas Source 11-03 .Intercepción de la interrupción 8 El código de intercepción de la interrupción 8h es similar a como lo hemos venido haciendo.8. El resultado es simular un reloj en modo texto. En la nueva ISR preservamos los registros que usamos e incrementamos el contador de pulsos y el puntero a las "agujas" guardadas en la variable "Indica".1. Cuando el contador de pulsos ha llegado a los dos segundos pintamos en la esquina superior derecha la aguja apuntada por .

esta rutina es el procedimiento "BCD2ASCII" que usa el acceso directo a memoria de vídeo para escribir en pantalla.Reloj interceptando Int 8h Primero guardamos la dirección de la ISR original de la Int 8h.6. Muestra teclado Echemos un vistazo al programa "KeybC?1.1.5."Posicion". A continuación la cambiamos por la nuestra.7.1. Hora y fecha actuales . Este ejemplo es interesante.1.8. situada en el procedimiento "Reloj". lo veremos en el siguiente capítulo.8. Reloj en tiempo real Vamos a ver otro ejemplo de intercepción de la Int 8h para mostrar en la esquina superior derecha de la pantalla un reloj en tiempo real. muy útil en los videojuegos. Además limpiamos la variable que cuenta los pulsos.asm" que finalmente colgué en el capítulo 9. En este ejemplo interceptamos la Int 9h para mostrar gráficamente qué teclas pulsamos y soltamos. por lo que necesitamos una rutina que lo convierta a ASCII y lo imprima por pantalla. Para obtener la hora actual accedemos al CMOS a través de los puertos 71h y 72h (más información en el siguiente capítulo) que se encuentran en formato BCD empaquetado. 11. Una vez establecida nuestra rutina esperamos con un bucle a pulsar la tecla escape.1. el cuál movemos un punto a la derecha hasta que llega a la última aguja. 11.. pues es la bas e para la construcción de un TSR que muestre por pantalla un reloj en tiempo real en la esquina superior izquierda de la pantalla.4. Obsérvese que para hacer un salto lejano en NASM es necesario el uso del prefijo "FAR" delante de la dirección a saltar.8. Además tenemos la posibilidad de pulsar varia s teclas a la vez. 11. tras lo cuál restituimos la ISR original de la Int 8h. RelojCM1 RelojCF1 RelojCN1 Resultado en pantalla Código [bin] Código [bin] Código 17:01:14 [bin] C:\Trabajo\AOE\Codigos\Cap11>RelojCM1 Source 11-06 . en cuyo caso le hacemos apuntar a la primera.

Si ejecutamos de nuevo el programa.En este ejemplo no interceptamos interrupciones. de modo que tendremos este servicio disponible hasta que otro programa pise el código de nuestra ISR o cerremos nuestra sesión de MS-DOS.1. deberíamos dejarlo en su formato original. para lo que definimos la etiqueta "NumVect" que apunta al número de la sentenci a "INT 0". no hacerlo . simplemente.Búsqueda de un vector de interrupción libre Observamos en la salida la cadena de texto imprimida por nuestra ISR. Establece rutina propia para interrupción Vamos a ver un ejemplo con sintaxis FASM (otras dos también disponibles) de cómo establecemos nuestra propia rutina ISR en un vector de interrupción libre que luego podremos usar con una instrucción "Int" normal: VectLCM1 VectLCF1 VectLCN1 Resultado en pantalla Código Código Código C:\Trabajo\AOE\Codigos\Cap11>VectLCF1 El vector 80h está libre Este es un mensaje desde la interrupcion 80h C:\Trabajo\AOE\Codigos\Cap11>VectLCF1 [bin] [bin] [bin] El vector 81h está libre Este es un mensaje desde la interrupcion 81h C:\Trabajo\AOE\Codigos\Cap11> Source 11-08 . De esta forma usamos nuestra ISR como un procedimiento cualquiera con la salvedad de que la llamamos con una interrupción en lugar de un "CALL". Normalmente.8. Un hecho destacado en este código es que usamos un artificio para modificar el código en ejecución. tras haber finalizado su trabajo. el vector 80h ya no está libre porque lo ocupamos en la anterior ejecución. que modificamos en cuanto conocemos el número de vector libre. usamos éstas para obtener la fecha y hora actuales. Podemos comprobar haciendo otro programa que podemos llamar a la interrupción 80h y nos imprimirá un mensaje (el número de interrupción libre que mostrará será el último establecido).Hora y fecha actuales con interrupciones 11.8. cuando modificamos un ve ctor de interrupción. IntCM5 IntCF5 IntCN5 Resultado en pantalla Código [bin] Código Código [bin] [bin] C:\Trabajo\AOE\Codigos\Cap11>IntCN5 La fecha actual es 01 -08-2010 La hora actual es 17:11:04 Source 11-07 .

. pues así nos aseguramos que esa porción de memoria ocupada por nuestra ISR no va a ser pisada por ningún otro código. normalmente haciendo que la función 0 del gestor de la interrupción devuelva una cadena o un código identificativo que otros programas podrán testear antes de usarlo. si AH posee cualquier otro valor indica que no existe esa función. Para ello comprueba que no es un vector de interrupción libre. Buscar Interrupción Supongamos que hemos instalado una interrupción que alguien quiere usar pero no sabe dónde está. si AH=1 ejecuta la función 1 que manda un mensaje a pantalla y si AH=2 ejecu ta la función 2 que manda otro mensaje a pantalla.Creamos interrupción con funciones e identificación Primero buscamos un vector de interrupción libre y aquí establecemos la dirección de nuestra ISR que chequea si le pedimos su identificación (AH=0) en cuyo caso devuelve AX=1212h. 2 y 3. En este programa no lo hemos hecho porque el objetivo perseguido es mostrar el uso de nuestra ISR con una instrucción "Int". 11.así puede resultar peligroso.8. Para resolver este problema debemos dotar a nuestra ISR de un método de identificación.1. en cuyo caso le pide que se identifique y si el resultado devuelto es el correcto llama a las funciones 1. cuando cargamos otro programa en memoria. La forma correcta de crear una interrupción y que ésta permanezca funcional en memoria indefinidamente es a través de una TSR que veremos en el capítulo siguiente. Tras esto buscamos la interrupción recién creada entre las 128 últimas posiciones de la tabla de interrupciones. Vamos a ver con un ejemplo todo ello dentro de un mismo programa por lo que acabamos de comentar. Además ya hemos visto que usualmente todas las interrupciones disponen de varias funciones ofreciendo un trabajo diferente según la elegida. lo más probable es que lo pise. VectLCM2 VectLCF2 VectLCN2 Resultado en pantalla Código Código Código c:\Trabajo\aoe\codigos\cap11>VectLCM2 Interrupcion establecida en el vector 80h Mensaje de la funcion 1 de la interrupcion 80h [bin] [bin] [bin] Mensaje de la funcion 2 de la interrupcion 80h No existe esta funcion Source 11-09 . Es importante recalcar que la interrupción que hayamos creado permanecerá funcional mientras no hay otro programa que pise el código de nuestra ISR.9.

que básicamente es un gestor de interrupciones.1. lo cuál implica ejecutar cada una de las interrupciones. por lo que si hacemos antes "MOV AL. por lo que no deberíamos terminar la Int 2Fh con un "IRET". cuando un programa necesita usar un código residente. el registro de banderas puede ser utilizado por algún gestor para devolver información. Como apunte intere sante. OldInt" cambia el valor de DS. se trata de la interrupción multiplex 2Fh. para encontrar una interrupción teníamos que recorrer el vector de interrupciones y preguntar por ella. en principio.asm. [OldInt]". el desarrollo es similar al VectLC?2. Disponemos de un mecanismo mucho más eficiente y elegante desde la versión 3. 11. por lo que deberemos interceptarla como ya sabemos dejando una puerta abierta para ejecutar la ISR estándar en el caso de que no pasemos por nuestro código. NumIntL" fallará por razones obvias. cabe destacar que en el procedimiento RestoreOldInt la orden "LDS DX. En nuestra ISR "NueVector" comprobamos que preguntan por nosotros mirando si AH = C0h.0 del MS-DOS. Para engancharse a la interrupción múltiple. Si nos buscaban a nosotros. Además. no tenemos por qué saber nada y lo normal será que se bloquee el sistema. usaremos en su lugar "RET n" donde n indica el número de bytes adicionales a extraer de la pila. genera una interrupción 2Fh. Interrupción Multiplex Hasta ahora. VectLCM3 VectLCF3 VectLCN3 Resultado en pantalla Código [bin] Código [bin] Código [bin] c:\Trabajo\aoe\codigos\cap11>VectLCN3 Mensaje de la funcion 1 Source 11-10 . quizás ya te hayas percatado que tanto en FASM como en NASM hay qu e utilizar "LDS DX. puesto que existen multitud de programas que también la siguen utilizando. Probamos nuestro código con el procedimiento "LlamaInt" donde prime ro comprobamos que está . En AH debe ir el identificador de la interrupción. Puesto que ésta es una interrupción software. si no es así saltamos a la ISR original de 2Fh.9.Creamos interrupción con funciones e identificación vía múltiplex Antes de interceptar la interrupción 2Fh guardamos su dirección del vector de interrupciones para restablecerla al final del programa. Obsérvese que Int 2Fh equivale a "PUSHF" y "CALL 2Fh". Es natural estremece rse ante este sistema porque podemos llegar a ejecutar cientos de códigos de los que.Finalmente restablece el valor original en el vector de interrupciones y sale al DOS. no debemos sustituirla sin más.

.disponible y a continuación la llamamos de nuevo usando la función AL = 1 para mostrar un mensaje por pantalla.

You're Reading a Free Preview

Descarga
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->