assembly - studio - ¿Qué hacer en el controlador de interrupción para dividir por cero?
visual studio installer (2)
En general, para codificar errores solo hay 2 opciones:
a) Termine el proceso. Esto puede o no incluir hacer otras cosas (registrar el error, crear un volcado del núcleo, etc.).
b) Permita que el proceso (que ni siquiera puede ejecutar correctamente la ejecución normal) intente su propia recuperación (lo cual es más difícil de hacer y probar que la ejecución normal). Un ejemplo de esto son las señales.
¿Qué debe hacer un controlador de interrupción del sistema operativo para las interrupciones relacionadas con los errores de codificación?
Por ejemplo, traté de dividir por 0 para probar mi interrupción y se llamó a mi controlador de interrupción. Sin embargo, debido a que la instrucción div no se ejecutó con éxito, EIP no se actualiza a la siguiente instrucción después de ella y luego de regresar del manejador de interrupciones con iret
, vuelve a la instrucción div
errónea nuevamente.
mov ax, 3
mov dl, 0
div dl ; go back here again and again
¿Cuál es la forma correcta de manejar esta interrupción? Algunas de las formas en que pensé:
Cambie
dl
a algo más que no sea 0. Sin embargo, no estoy seguro de sidl
puede mantener si sucede algo, y se supone que la rutina de interrupción restaura los registros después de la salida, y no creo que se corrija silenciosamente un error al proporcionar un cálculo incorrecto. bueno.Recupere la siguiente instrucción después de
div
. Sin embargo, no he pensado en ninguna manera simple y confiable de obtener la siguiente instrucción.Modifique la parte superior de la pila que actualmente contiene la dirección de retorno a la dirección de otro código. Entonces, ya no volvemos a la instrucción
div
.
Tienes razón en que ninguno de ellos es particularmente bueno en el caso de esta interrupción en particular. Como se mencionó en los comentarios, dado que tiene la dirección de la instrucción, puede buscar lo que esté en esa dirección, decodificar las instrucciones y luego avanzar el puntero a la dirección siguiente ... ¡pero el código no lo habrá esperado!
En los sistemas operativos POSIX este comportamiento excepcional está cubierto por la señal SIGFPE. Si estaba escribiendo un sistema operativo y quería seguir POSIX, su controlador de interrupción debería enviar esa señal al proceso. Si el proceso tiene un controlador para esa señal, salte a eso y permita que el proceso maneje esto (por ejemplo, así es como podría funcionar un bloque try / catch en un lenguaje de alto nivel ... ahora usted sabe por qué las excepciones son lentas !). Si no hay un manejador de señal, entonces el proceso debería ser eliminado (y vuelva a ingresar a su programador para averiguar qué hacer a continuación ... ¡y espero que sea el PID 1!).
Por supuesto, este es su sistema operativo, y no hay ninguna razón por la que tenga que seguir POSIX si no lo desea. Si tiene alguna otra forma elegante de manejar un error en un programa de usuario, entonces puede implementarlo.