Para evitar esto, es indispensable el apoyo del hardware, a través de los siguientes mecanismos.
El bit de modo indica el modo de operación actual. Cuando se enciende el computador y se carga el sistema operativo, se comienza en modo sistema. El sistema operativo siempre cambia a modo usuario antes de pasar el control a un proceso de usuario. Cuando ocurre una interrupción, el hardware siempre cambia a modo sistema. De esta menera, el sistema operativo siempre ejecuta en modo sistema. ¿Cual es la gracia? Que hay ciertas operaciones críticas que sólo pueden ser ejecutadas en modo sistema.
Para que este mecanismo de protección sea completo, hay que asegurarse que los programas de usuario no puedan obtener acceso a la CPU en modo sistema. Por ejemplo, un programa de usuario podría poner una dirección que apunte a una rutina propia en el vector de interrupciones. Así, cuando se produzca la interrupción, el hardware cambiaría a modo sistema, y pasaría el control a la rutina del usuario. O, también, el programa de usuario podría reescribir el servidor de la interrupción. Se requiere entonces...
Para que esto funcione, hay que comparar cada dirección accesada por un programa en modo usuario con estos dos registros. Si la dirección está fuera del rango, se genera una interrupción que es atendida por el sistema operativo, quien aborta el programa (usualmente con un lacónico mensaje "segmentation fault"). Esta comparación puede parecer cara, pero teniendo presente que se hace en hardware, no lo es tanto. Obviamente, el programa usuario no debe poder modificar estos registros: las instrucciones que los modifican son instrucciones protegidas.
Entonces, ¿cómo hace I/O un programa de usuario, si sólo el sistema operativo puede hacerlo? El programa le pide al sistema operativo que lo haga por él. Tal solicitud se conoce como llamada al sistema, que en la mayoría de los sistemas operativos se hace por medio de una interrupción de software o trap a una ubicación específica del vector de interrupciones. Ejemplo hipotético, (parecido a MSDOS), para borrar un archivo:
Como la llamada es a través de una interrupción, se hace lo de siempre: cambiar a modo protegido, y pasar control a la dirección en la posición 4*21h del vector de interrupciones, o sea, a la rutina que maneja las llamadas al sistema (o tal vez, la rutina que maneja las llamadas que tienen que ver con archivos; puede que otras clases de llamadas sean atendidas por medio de otras interrupciones). Dicha rutina examina el registro A para determinar qué operación debe ejecutar, y después determina el nombre del archivo a través del registro B. En seguida, decide si la operación es válida: puede que el archivo no exista o pertenezca a otro usuario; según eso, borra el archivo o "patalea" de alguna manera.
Cuando uno hace esto en un lenguaje de alto nivel, como C, simplemente escribe:
char* Nombre = "Datos"; remove(Nombre);
El compilador de C es quien se encarga de traducir esto a una llamada al sistema, ocultando el detalle de la interfaz con el sistema operativo.