Como se mencionó anteriormente, la arquitectura (repertorio de instrucciones, organización de la memoria, E/S y estructura del bus) de la mayoría de los ordenadores al nivel del lenguaje máquina es primitiva y muy difícil de programar, especialmente en lo que respecta a la entrada/salida. Para hacer este punto más concreto, veamos brevemente cómo se realiza la E/S desde la disquetera utilizando un chip controlador compatible con el NEC PD765 como el que se utiliza en la mayoría de los ordenadores personales basados en Intel. El controlador PD765 tiene 16 instrucciones, cada una de las cuales se especifica cargando entre uno y nueve bytes en un registro de dispositivo. Estas instrucciones son para leer y escribir datos, mover el brazo del disco y formatear pistas, así como para inicializar, detectar, resetear y recalibrar el controlador y las unidades de disco.

Las instrucciones más básicas son read y write, cada una de las cuales requiere 13 parámetros, comprimidos en 9 bytes. Estos parámetros especifican la dirección del bloque de disco a leer, el número de sectores por pista, el modo de grabación empleado sobre el medio físico, la separación entre sectores, qué hacer con una marca de dirección de datos borrada, y cosas por el estilo. Si el lector no entiende esta jerga, no debe preocuparse; de hecho, eso es precisamente lo que se quiere poner de manifiesto: que todo el asunto es un tanto esotérico. Una vez que se lleva a cabo la operación, el controlador devuelve 23 campos de estado y error comprimidos en 7 bytes. Por si no fuera suficiente, en todo momento el programador de la disquetera debe preocuparse también de saber si el motor está encendido o apagado. Si está apagado, habrá que encenderlo (con un largo retraso hasta que el disquete adquiera la velocidad adecuada) antes de poder leer o escribir los datos. Pero el motor no puede quedarse encendido demasiado tiempo, ya que en ese caso el disquete se desgastaría rápidamente. Así, el programador se ve forzado a encontrar una solución de compromiso entre tener largos retrasos de arranque o permitir peligrosos desgastes del disquete (con la posibilidad de perder datos grabados).

Sin entrar en los detalles reales, debe quedar claro que es probable que el programador medio no quiera involucrarse demasiado íntimamente con los pormenores de la programación de los disquetes (o discos duros, que son igual de complejos aunque muy diferentes). En vez de eso, lo que el programador quiere es trabajar con una abstracción de alto nivel sencilla. En el caso de los discos, una abstracción típica sería que el disco contiene una colección de ficheros con nombre. Cada fichero puede abrirse para lectura o escritura, para luego leer o escribir en él, debiendo finalmente cerrarse. Los detalles de si la grabación debe realizarse por modulación de frecuencia modificada o si el motor está encendido o apagado, no deben aparecer en la abstracción que se presenta al usuario.

El programa que oculta al programador la verdad acerca del hardware y presenta una visión bonita y sencilla de ficheros con nombre que se pueden leer y en los que se puede escribir, es por supuesto, el sistema operativo. Así como el sistema operativo separa al programador del hardware del disco y presenta una interfaz sencilla orientada hacia los ficheros, también oculta muchos otros asuntos desagradables relacionados con las interrupciones, timers, gestión de memoria y otras características de bajo nivel. En cada caso la abstracción que ofrece el sistema operativo es más sencilla y más fácil de usar que la que ofrece el hardware subyacente.

Desde esta perspectiva, la función del sistema operativo es presentar al usuario el equivalente de una máquina extendida o máquina virtual que es más fácil de programar que el hardware subyacente. La forma en la que el sistema operativo logra este objetivo es una larga historia, que estudiaremos en detalle a lo largo del libro. En pocas palabras, el sistema operativo presta una variedad de servicios que los programas pueden obtener empleando instrucciones especiales que se conocen como llamadas al sistema. Examinaremos algunas de las más comunes en una sección posterior de este capítulo.