Petición de interrupción
El proceso de sincronización por interrupción se inicia cuando el controlador informa al procesador,
mediante una petición de interrupción, de que ha ocurrido un evento que requiere su atención.
Lógicamente, si el controlador no está capacitado para generar tal petición entonces la sincronización por
interrupción entre el procesador y el controlador no es posible.
En la descripción de un controlador debe siempre quedar claro en qué condiciones el controlador generará
una petición de interrupción. En el caso de los controladores con los que trabajamos es este curso, los
motivos de interrupción se recogen en la tabla siguiente.
Algunos controladores tienen un bit en el registro de control que se utiliza para inhibir las interrupciones
del controlador. Por ejemplo, el procesador puede inhibir las interrupciones del controlador de impresora
poniendo un 0 en el bit 0 del registro de control (sin alterar el resto de los bits de este registro). El código
necesario para hacer esta operación es:
IN AL, Rcont_imp
AND AL, 11111110b; pone a 0 el bit 0 sin modificar los otros bits
OUT Rcont_imp, AL
El controlador de teclado no tiene registro de control (y por tanto, no tiene bit de inhibición de
interrupciones. Las interrupciones en el controlador de disco se inhiben poniendo a 0 el bit 0 del registro
de control Rcont_disc.
A menos que se especifique lo contrario, supondremos que las interrupciones están permitidas en el
controlador (es decir, el bit correspondiente del registro de control está a 1). Por tanto, la operación de
inhibición de la interrupción será necesaria cuando se quiera realizar una sincronización por encuesta. En
ese caso, además, antes de finalizar el programa deberán restaurarse las interrupciones inhibidas,
volviendo a poner un 1 en el bit correspondiente del registro de control.
1
Búsqueda
Fetch Decodificación
operandos
NO
¿Interrupción Almacenamiento
pendiente? Ejecución
resultado
SI
Tratamiento
Es importante comprender que una petición de interrupción que se produzca mientras el procesador está
ejecutando una instrucción no será atendida por el procesador hasta que éste finalice la ejecución de la
instrucción. Esta circunstancia puede resultar problemática cuando la instrucción en curso tiene un tiempo
de ejecución grande, ya que en ese caso podría pasar un tiempo excesivo entre el instante en que el
controlador solicita la atención del procesador y el instante en que el procesador inicia la atención,
pudiéndose producir como resultado un error de funcionamiento del sistema.
¿Qué harías cuando existe realmente este riesgo? Describir una situación en la que esto puede ocurrir.
El procesador tiene un bit que le permite protegerse de las interrupciones. En el caso del i80X86, este bit
es el IF (Interrupt flag) que está en la palabra de estado (EFLAGS). Mientras el bit IF esté a 0 el
procesador ignorará cualquier petición de interrupción. El valor del bit IF se controla mediante dos
instrucciones de lenguaje máquina (son instrucciones sin operandos):
CLI pone el bit IF a 0 (inhibe las interrupciones en el procesador)
STI pone el bit IF a 1 (permite las interrupciones en el procesador)
Inhibir las interrupciones en el procesador es una operación peligrosa porque deja sin atención a todos los
controladores. Tal y como se ha mencionado antes, esto puede provocar un mal funcionamiento del
sistema. Por ese motivo, en muchos sistemas las instrucciones tipo CLI y STI son privilegiadas (no
pueden formar parte del programa de un usuario normal). Tal y como usamos nosotros el PC, nuestros
programas si podrán usar las instrucciones CLI y STI.
Finalmente, hay que comprender también que la instrucción CLI inhibe todas las interrupciones. Si sólo
queremos inhibir las interrupciones de un controlador determinado entonces hay que usar el bit de
inhibición de interrupción que tiene el registro de control del controlador en cuestión (si es que ese bit
existe).
2
Identificación del motivo de la interrupción
Habitualmente, el sistema que usa el procesador para detectar peticiones de interrupción sólo le permite
averiguar que existe un controlador que requiere su atención. El procesador debe ahora averiguar cuál de
los posibles controladores es el que ha solicitado la interrupción. Además, puede ocurrir que sean varios
los han pedido interrupción. En ese caso, será necesario determinar cuál de los controladores es atendido.
El problema de la identificación del motivo de la interrupción puede resolverse por software o por
hardware.
Solución software
En este caso, después de salvar el contexto del programa interrumpido, el procesador pasa a ejecutar una
rutina de atención a las interrupciones. Se trata de la única rutina de atención a las interrupciones y
siempre se ejecuta la misma.
Las primeras instrucciones de la rutina determinan cuál es el controlador que ha realizado la petición.
Para ello, se consulta el valor del registro de estado de cada uno de los controladores hasta encontrar uno
que indique que el controlador requiere atención (recuérdese que la consulta del registro de estado es la
idea en la que se basa la sincronización por encuesta). Por ejemplo, la rutina de atención a las
interrupciones podría comenzar así:
Rsi PROC
IN AL, Rest_K1
TEST AL, 00000001b
JNE atención_K1
IN AL, Rest_K2
TEST AL,00000001b
JNE atención_K2
…
En el código anterior se ha supuesto que en ambos controladores (K1 y K2) es el bit 0 del registro de
estado el que indica que el controlador está esperando el tratamiento por parte del procesador.
En el caso en que varios controladores estén pendientes de atención entonces el orden en el que la rutina
de atención consulta los registros de estado determina el orden de prioridad de los controladores. En el
caso del código anterior, si K1 y K2 solicitan interrupción al mismo tiempo, entonces K1 será atendido
antes que K2.
Identificación hardware
En este caso, hay una rutina de atención diferente para cada uno de los controladores que pueden
interrumpir. Existe un sistema hardware, externo al procesador (que se estudia más adelante en este curso)
que averigua cuál es el controlador que ha interrumpido y que hace que el procesador, después de salvar
el contexto del programa interrumpido, salte a ejecutar directamente la rutina de atención adecuada.
Además, el sistema hardware decide qué controlador tiene prioridad en caso de que haya varias peticiones
simultáneas pendientes.
3
i80X86 a partir de la dirección física 0 de memoria. Los identificadores de interrupción de cada uno de
los controladores con los que trabajamos en este curso son:
Reloj 8
Teclado 9
Disco 13
Impresora 15
Cuando se escribe un programa para el i80X86 en el que debe haber una sincronización por
interrupciones con un controlador determinado, entonces, además de escribir la rutina que queremos que
se ejecute cada vez que se produzca una interrupción de ese controlador, habrá que colocar en la posición
correspondiente del vector de interrupciones el puntero a la posición en que comienza la rutina de
atención. Además, antes de acabar, el programa deberá restaurar el vector de interrupciones con sus
valores originales, para dejar el sistema en las misma condiciones en las que estaba antes de iniciarse la
ejecución de nuestro programa.
Desplaz.
i
Seg.
Puntero (4 bytes) a la
rutina de atención
Salvar el estado
Nos encontramos ya al inicio de la rutina de atención a la interrupción. Lo primero que debe hacer esa
rutina es salvar en la pila el valor de los registros que van a usarse durante la ejecución de la rutina. Esos
valores se restaurarán antes de retornar al programa interrumpido, para que éste se reanude exactamente
en la misma situación en que fue interrumpido (el problema es análogo al caso de las subrutinas).
4
Eliminar la petición de interrupción
Se trata de informar al controlador de que el procesador ha decidido ya atender su petición de
interrupción, para que el controlador retire la petición. Si no se hace esta operación entonces, más
adelante, durante la ejecución de la rutina de atención de la interrupción, el procesador puede detectar una
nueva petición de interrupción del mismo controlador, que es en realidad la petición anterior que aún no
ha sido retirada. Esta situación provocaría un error en el funcionamiento del sistema.
La eliminación de la petición puede realizarse por software o de forma automática (por hardware).
Eliminación automática
En este caso, el mismo sistema hardware que identifica el controlador que debe ser atendido informa
también al controlador para que elimine ya la petición. Por tanto, al escribir la rutina de atención a las
interrupciones no es necesario preocuparse de la eliminación de la petición ya que esta operación se
realiza de forma automática.
Para cada controlador habrá que tener presente si las interrupciones se eliminan por software o de forma
automática. La siguiente tabla resume el caso de cada uno de los controladores usados en este curso.
Al escribir una rutina de atención debe tenerse en cuenta que durante la ejecución de la rutina las
interrupciones están inhibidas. Por tanto, la rutina debe ser rápida para evitar que otras peticiones de
interrupción deban esperar mucho tiempo para ser atendidas. En particular, deben evitarse los bucles en
las rutinas de atención a las interrupciones.
En cualquier punto de la rutina pueden permitirse las interrupciones (ejecutando la instrucción STI).
Debe tenerse muy en cuenta que, en ese caso, la rutina que se está ejecutando será abandonada
temporalmente si se produce otra interrupción, y, por tanto, el tratamiento de la interrupción se demorará.
Restaurar el estado
Tal y como ya se ha mencionado, antes de finalizar la rutina de atención deben restaurarse los valores de
los registros utilizados, que fueron salvados en la pila al inicio de la rutina.
5
Retorno al programa interrumpido
Esta operación se consigue ejecutando la instrucción IRET, que debe ser la última de la rutina de
atención a la interrupción.
La instrucción IRET toma de la pila la dirección de retorno y el valor de la palabra de estado (que fueron
salvados en la pila por el procesador cuando decidió aceptar la interrupción).
Después de ejecutar la instrucción IRET, el procesador ejecuta siempre la siguiente instrucción del
programa interrumpido, incluso aunque haya una nueva petición de interrupción pendiente. De esta forma
se garantiza que el programa interrumpido puede avanzar en su ejecución a pesar de que se produzcan
múltiples interrupciones.
Preguntas
¿Cuál es el código necesario para restaurar las interrupciones del controlador de disco?
Describe una situación en la que puede ser peligroso inhibir las interrupciones en el procesador
¿Por qué no es necesario salvar en la pila los bits de condición en el caso de una llamada a subrutina y si
lo es cuando el procesador decide atender una interrupción?
¿Qué ocurriría si la rutina de atención a la interrupción del teclado no leyese el registro de datos?
¿Por qué hay que evitar los bucles en las rutinas de atención a las interrupciones?
¿Por qué el procesador no atenderá ninguna interrupción inmediatamente después de ejecutar un IRET?