Diferencias rutina interrupción/rutina general - x86

Diferencias rutina interrupción/rutina general - x86

de Ignacio Rafael Ferreira Urrutia -
Número de respuestas: 2

Buenas, no pude asistir al taller de interrupciones y tenía algunas dudas, cuales serían las diferencias entre una rutina de no interrupciones y una de interrupciones en assembler?. En alto nivel tenía entendido que el manejo de interrupciones se hacía solo y solo había que hacer el enable en el main, pero no me queda claro si en assembler es necesario cierto manejo adicional. Las diferencias que encontré son las siguientes:

  • Al hacer una rutina de interrupciones el encabezado es PROC FAR para que se guarde el segmento también
  • Se sustituye el enable por STI
  • Se definen variables en el código assembler como alternativa a los registros
  • Se cambia RET por IRET en la rutina de interrupción
Es esto correcto? Resta algún otro cambio? Es necesario hacer CLI antes de habilitar las interrupciones en assembler o ya se hace solo en el main?

A que se refiere el handler de interrupciones?
Busqué en los pdf pero no encontré mucho sobre el tema interrupciones en x86, alguien tiene idea o sabe alguna bibliografía donde pueda consultar este tema?
Saludos
En respuesta a Ignacio Rafael Ferreira Urrutia

Re: Diferencias rutina interrupción/rutina general - x86

de Gustavo Brown -

Hola,

  Te comento entre líneas:

  • Al hacer una rutina de interrupciones el encabezado es PROC FAR para que se guarde el segmento también

    • Esto no es estrictamente necesario porque no deberías llamar a la rutina de interrupción "a mano". La palabra FAR o NEAR en el código assembler sirve para indicarle al ensamblador que dentro de la rutina si aparece un RET éste debe ser FAR, es decir la variante de la instrucción RET que quita CS además de IP. También le indica al ensamblador que si alguien hace un CALL a dicha rutina, se debe usar la variante del CALL que es FAR. Notar que (ver punto más abajo) la rutina que atiende la interrupción debería terminar con un IRET y no con un RET por lo que indicar que sea FAR o NEAR no va a tener consecuencias. Y también debes recordar que al llamarse una rutina de interrupción no solo se guarda el IP y CS sino que también se guardan las flags.
  • Se sustituye el enable por STI
    • Correcto, la instrucción en 8086 para habilitar interrupciones es STI
  • Se definen variables en el código assembler como alternativa a los registros
    • Esto es cierto a medias. La opción de utilizar variables globales en memoria vale en todo momento, no solo cuando estamos implementando rutinas de atención a interrupciones (nota aparte: en el caso de rutinas recursivas no es buena idea usar variables globales porque hay una sola copia de las mismas). El punto es que para mantener el estado del sistema no deberías utilizar registros si estás implementando una rutina que atiende una interrupción porque los registros deberían quedar como estaban al terminar la rutina. Por eso es que se usan variables en memoria para mantener el estado. 
      Para el caso de variables globales utilizadas dentro de rutinas que atienden interrupciones lo que tenes que asumir es que la sección de datos del programa apunta al mismo segmento que la sección de código (es decir CS=DS cuando arranca el main)
  • Se cambia RET por IRET en la rutina de interrupción
    • Correcto. Una rutina que atiende una interrupción debe terminar en un IRET para que la CPU restaure IP, CS y FLAGS
  • Es necesario hacer CLI antes de habilitar las interrupciones en assembler o ya se hace solo en el main?
    • La CPU cuando se resetea arranca con las interrupciones deshabilitadas. De cualquier manera en tu main deberías deshabilitarlas antes de instalar las interrupciones (mediante la instruccion CLI) porque no sabes si el que invocó a la rutina main las habilitó antes de llamarte.
  • A que se refiere el handler de interrupciones?
    • El  handler de una interrupción es la rutina que atiende la interrupción
Saludos,
  Gustavo