En primer lugar, soy un principiante, por lo que si esta pregunta suena tonta, por favor señale los supuestos incorrectos.
Por lo que entiendo, el trabajo de un sistema operativo es administrar el hardware y el software que se ejecuta en el sistema operativo. Además, por lo que entiendo, los programas de ensamblaje permiten controlar el hardware casi directamente. En un programa de ensamblaje, uno puede leer y escribir datos en registros, y leer y escribir datos en RAM.
Dada esta libertad de meterse con los registros y la RAM, ¿no sería posible que los programas de ensamblaje afecten el sistema operativo? Suponga que un sistema operativo está utilizando el registro A para almacenar información crucial, y suponga que ejecuto un programa ensamblado en ese sistema operativo. Si el programa escribe correctamente la basura en el registro A, el sistema operativo seguramente se verá afectado.
Preguntas:
¿Es posible meterse con el registro A de la manera descrita anteriormente?
Si no, ¿qué impide que los programas de ensamblaje modifiquen los registros utilizados por el sistema operativo?
Respuestas:
Al final, todos los programas son código de máquina, independientemente de si el idioma de origen era ensamblador o un lenguaje de alto nivel.
Lo importante es que existen mecanismos de hardware que limitan lo que puede hacer un proceso determinado, incluidos los registros de "jugar con" que podrían afectar a otros programas o al propio sistema operativo.
Esto comenzó con una simple distinción entre los modos de operación "usuario" y "supervisor", y desde entonces se ha convertido en una arquitectura de seguridad con múltiples "anillos" de privilegios.
Aquí hay un ejemplo muy genérico para hacerlo un poco más concreto:
En "modo de usuario", un proceso no puede acceder a la memoria que no ha sido asignada a su ID de proceso. La memoria asignada a otros procesos y el propio sistema operativo está bloqueado. Esto incluye los valores de los registros utilizados por esos otros procesos. Esto es impuesto por el hardware MMU.
Por lo tanto, en "modo de usuario", un proceso no puede acceder a los registros de control de MMU.
Y, obviamente, en "modo de usuario", un proceso no puede cambiar el modo a "modo de supervisor", excepto a través de un mecanismo muy bien definido que implica llamar a una función del sistema operativo.
El sistema operativo obtiene el control si el proceso intenta romper alguna de estas reglas. Una vez que eso sucede, el sistema operativo simplemente puede detener el proceso ofensivo, sin ejecutar más instrucciones.
fuente
Muchos sistemas operativos multitarea utilizan una estructura de datos llamada bloque de control de procesos (PCB) para solucionar el problema de sobrescritura de registros. Cuando ejecuta su código, el sistema operativo crea un nuevo proceso para realizar un seguimiento. El PCB contiene información sobre su proceso y el espacio asignado para contener el contenido del registro. Digamos que el proceso A se está ejecutando actualmente en el procesador y su código está en proceso B. Lo que sucede cuando ejecuta su código es algo así:
Los datos de estado del proceso A (contenido del registro, contador del programa, etc.) se copian en su PCB.
Los datos de estado del proceso B se copian de su PCB en los registros de la CPU
El proceso B se ejecuta en el procesador hasta que finaliza o se adelanta
Los datos de estado del proceso B se vuelven a copiar en su PCB
Los datos de estado del proceso A se vuelven a copiar en la CPU y continúa ejecutándose
Si el sistema operativo se está ejecutando como el proceso A, puede ver cómo guardar sus registros antes de que se ejecute su programa y luego copiarlos nuevamente en la CPU una vez que finaliza su programa evita que los programas del usuario se enreden con lo que sucede en otros procesos.
Para evitar que los procesos del usuario escriban sobre los datos del sistema operativo en la memoria, la mayoría de las plataformas utilizan la segmentación de la memoria. Básicamente, utilizando la memoria virtual, el espacio de direcciones que ve un proceso puede asignarse a cualquier rango arbitrario de direcciones físicas. Mientras los espacios de memoria física de los procesos no se superpongan, es imposible que un proceso sobrescriba los datos de otro.
Por supuesto, los diferentes sistemas operativos hacen las cosas de manera diferente, por lo que esto no se aplicará en todos los casos. Además, en la mayoría de las plataformas, los procesos del sistema operativo se ejecutan en un modo diferente de los procesos del usuario y hay algunas complejidades allí.
fuente
Depende de la plataforma de la que estés hablando.
En un procesador más básico, el procesador solo ejecuta las instrucciones que el programa le dice que ejecute.
En un procesador más sofisticado, hay (al menos) dos modos. En un modo, el procesador hace lo que el programa le dice que haga. En el otro modo, el procesador se niega a ejecutar ciertas instrucciones.
¿Qué detiene un programa que bloquea todo el sistema? Con el primer tipo de procesador, la respuesta es "nada". Con un procesador básico, un solo programa no autorizado puede bloquear el sistema completo. Todas las primeras computadoras domésticas de 8 bits, y muchas de las de 16 bits, entran en esta categoría.
En una PC moderna, el procesador tiene hardware de "protección". Básicamente, el sistema operativo se ejecuta en un modo especial que le permite hacer cualquier cosa, mientras que los programas normales se ejecutan en un modo en el que el procesador solo permitirá ciertas acciones (según la configuración que el sistema operativo haya configurado en el procesador). Cosas como solo acceder a ciertos registros, o solo acceder a rangos de memoria particulares.
Obviamente, permitir que un solo programa malintencionado bloquee todo el sistema es malo. (También hay graves implicaciones de seguridad al permitir que un programa no autorizado acceda a los datos que desee). Para evitar esto, necesita dos cosas:
Un procesador que realmente tiene hardware de protección (es decir, puede configurarse para negarse a ejecutar ciertas instrucciones).
Un sistema operativo que realmente utiliza estas instalaciones para protegerse. (¡No es bueno tener un chip con circuitos de protección si el sistema operativo nunca lo usa!)
Casi cualquier SO de escritorio moderno que pueda nombrar (Windows, Linux, Mac OS, BSD ...) es un SO en modo protegido que se ejecuta en un procesador con hardware de protección. Si está realizando un desarrollo integrado en algún microcontrolador de 8 bits, probablemente no tenga ningún hardware de protección. (O cualquier sistema operativo, para el caso ...)
fuente
P. ¿Qué impide que un programa de ensamblaje bloquee el sistema operativo?
A. nada.
Sin embargo, muchos programadores muy inteligentes se han esforzado mucho a lo largo de los años para hacerlo cada vez más difícil. Desafortunadamente, para cada programador inteligente, hay muchos, muchos otros que entre ellos son más creativos, más ambiciosos y, a veces, más afortunados que los inteligentes. Cada vez que un programador inteligente dice que nadie debería, haría o podría hacer algo, alguien por ahí encontrará la manera de hacerlo. Microsoft Windows (como ejemplo) ha existido durante casi 35 años y todavía tenemos BSoD (pantallas azules de la muerte), que son solo instrucciones que bloquearon el sistema operativo.
Comencemos con un poco de terminología. Todo lo que se ejecuta en una computadora lo hace en código máquina. El bit que lee las pulsaciones de teclas o el movimiento del puntero del mouse, el bit que cambia el color de un píxel en la pantalla o lee un byte de un archivo y el bit que calcula si su bala golpeó al tipo malo o al bit que decide si su solicitud de tarjeta de crédito será aceptada, todas se ejecutarán como una secuencia de instrucciones de código de máquina. Algunos trabajos son tan comunes y se realizan con tanta frecuencia que tiene sentido reunir las instrucciones necesarias para hacerlos y hacer que todos usen ese ensamblaje. El conjunto de estos trabajos que permiten o ayudan a otros a usar la computadora tienden a llamarse sistema operativo, pero no hay nada inherentemente diferente entre ellos y cualquier otro programa. Todos son solo secuencias de instrucciones de código de máquina.
Lo que hace que los sistemas operativos sean más complicados (y, por lo tanto, propensos a fallar) es que tienen que dar cuenta de cosas en las que normalmente no tiene que pensar. Tome los trabajos más simples como ejemplo. Quiero escribir un mensaje al final de un archivo. En un lenguaje de alto nivel escribirías algo como:
Vamos a ignorar todos los detalles sobre cómo se accede y cambia los estados físicos o cómo se interpretan como bits y bytes o cómo esos bytes se transfieren hacia y desde la memoria y la CPU, y confíe en que todo eso es manejado por los programas que proporciona el sistema operativo entre bastidores. Solo pensemos en cómo se agrega al final de un archivo. 1) Averigüe dónde está el final del archivo, 2) escriba algo en esa posición. ¿Qué podría salir mal? En realidad, bastante. Piensa en qué más está sucediendo en la computadora mientras haces cosas inteligentes. Si cualquier otra cosa realizada por otra persona (incluido el propio sistema operativo) cambia el archivo en el que está trabajando de alguna manera, entonces este trabajo realmente simple de repente se vuelve mucho más complicado. El archivo es más largo, el archivo es más corto. El archivo ya no está allí. El disco está lleno,
fuente