Documentos de Académico
Documentos de Profesional
Documentos de Cultura
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. Pero 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.1. Polling
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 datos.
11.1.1.3. Conclusión
INT 2: Interrupción no
enmascarable. Tiene prioridad
absoluta y se produce incluso
aunque estén inhibidas las
interrupciones para indicar un
hecho muy urgente.
INT 4: Desbordamiento. Se
dispara cuando se ejecuta un INTO
y había desbordamiento. Si no hay
desbordamiento INTO equivale a
NOP.
INT F: Reservado
11.1.4.1. Localización
11.1.6. ISRs
Acrónimo de Interruption Service Routine o Rutina de Servicio a la
Interrupción. Es la rutina para cada tipo de interrupción. Ya hemos visto
que básicamente, cuando ejecutamos un "INT" metemos en la pila el
registro de banderas, el CS y el IP, que apuntan a la siguiente instrucción, 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, CS y del registro de banderas. Es decir, el funcionamiento es muy
similar al de una subrutina llamada con un "CALL" y terminada con un
"RET". 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.
Veamos algunas características y consejos interesantes de las ISR.
Pero ocurre una interrupción justo de pués de "MOV SS, AX". Ahora el
registro de pila SS contiene un valor, seguramente, diferente al esperado en
la ISR que ha tomado el control, con lo que el resultado puede ser
desastroso. Una forma de evitar esto es desactivando temporalmente las
interrupciones:
MOV AX, 9000h
CLI ; Deshabilitamos interrupciones
MOV SS, AX
MOV SP, 3000h
STI ; Habilitamos interrupciones
MUY IMPORTANTE
Cuando se intercepta una interrupción, con nuestra propia ISR, hay que procurar
preservar los registros de segmento, no sólo en la ISR, sino en el resto de
procedimientos que usemos fuera de ella, especialmente con las interrupciones del reloj.
En mi caso, he interceptado la 1Ch del reloj en el Tetris y me daba problemas algún otro
procedimiento. Tuve que poner en cada procedimiento explícitamente qué valían DS y
ES. Imagínate que usamos variables, pero nuestra rutina ya no sabe qué vale DS o ES,
podremos tener resultados insospechados.
Se puede reemplazar una rutina de interrupción con nuestro código, para lo
cuál debe cumplir:
11.1.8. Ejemplos
Veremos algunos códigos de ejemplo de intercepción de interrupciones.
Importante
Es más que conveniente ejecutar estos ejemplos desde la ventana de comandos de
Windows. Si posees un W95 o W98 te irán todos bien, pero si tienes un XP seguramente
no te funcionarán algunos, en este caso habría que echar mano de una plataforma como
DOSBox, especialmente los programas residentes. Y es que WXP no parece tratarlos
muy bien.
11.1.8.1. Int 4h
11.1.8.3. Int 9h
11.1.8.4. Int 8h
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:
Supongamos que hemos instalado una interrupción que alguien quiere usar
pero no sabe dónde está. Para resolver este problema debemos dotar a
nuestra ISR de un método de identificación, 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. Además
ya hemos visto que usualmente todas las interrupciones disponen de varias
funciones ofreciendo un trabajo diferente según la elegida. 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, cuando
cargamos otro programa en memoria, lo más probable es que lo pise. 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, 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. Vamos
a ver con un ejemplo todo ello dentro de un mismo programa por lo que
acabamos de comentar.