top of page

La segmentación es un método de manejo de memoria. La segmentación provee la base para la protección. Los segmentos se utilizan para encapsular regiones de memoria que tienen atributos comunes. Por ejemplo, todo el código de un programa dado podría estar contenido en un segmento, o una tabla del sistema operativo podría estar en un segmento. Toda la información sobre un segmento se almacena en una estructura de ocho bytes llamada descriptor. Todos los descriptores del sistema están en tablas en memoria que reconoce el hardware.

Bits de atributo del descriptor

El objeto apuntado por el selector se llama descriptor. Los descriptores son cantidades de ocho bytes que contienen atributos sobre una región de memoria (es decir, un segmento). Estos atributos incluyen la dirección base de 24 bits, la longitud de 16 bits, el nivel de protección (de 0 a 3), permisos de lectura, escritura o ejecución (esto último para segmentos de código), y el tipo de segmento. A continuación se muestra el formato general de un descriptor.

 

  • Byte 0: Límite del segmento (bits 7-0).

  • Byte 1: Límite del segmento (bits 15-8).

  • Byte 2: Dirección base del segmento (bits 7-0).

  • Byte 3: Dirección base del segmento (bits 15-8).

  • Byte 4: Dirección base del segmento (bits 23-16).

  • Byte 5: Derechos de acceso del segmento.

  • Bytes 6 y 7: No utilizados (deben valer cero para lograr la compatibilidad con 80386 y posteriores).

El byte de derechos de acceso es el que define qué clase de descriptor es. El bit 4 (S) indica si el segmento es de código o datos (S = 1), o si es del sistema (S = 0). Veremos el primer caso.

 

  • Bit 7: Presente (P). Si P = 1 el segmento existe en memoria física, mientras que si P = 0 el segmento no está en memoria. Un intento de acceder un segmento que no está presente cargando un registro de segmento (CS, DS, ES o SS) con un selector que apunte a un descriptor que indique que el segmento no está presente generará una excepción 11 (en el caso de SS se generará una excepción 12 indicando que la pila no está presente). El manejador de la interrupción 11 deberá leer el segmento del disco rígido. Esto sirve para implementar memoria virtual.

     

  • Bits 6 y 5: Nivel de privilegio del descriptor (DPL): Atributo de privilegio del segmento utilizado en tests de privilegio.

     

  • Bit 4: Bit descriptor del segmento (S): Como se explicó más arriba, este bit vale 1 para descriptores de código y datos.

     

  • Bit 3: Ejecutable (E): Determina si el segmento es de código (E = 1), o de datos (E = 0).Si el bit 3 vale cero:

    • Bit 2: Dirección de expansión (ED): Si E = 0, el segmento se expande hacia arriba, con lo que los offsets deben ser menores o iguales que el límite. Si E = 1, el segmento se expande hacia abajo, con lo que los offsets deben ser mayores que el límite. Si no ocurre esto se genera una excepción 13 (Fallo general de protección) (en el caso de la pila se genera una excepción 12).

    • Bit 1: Habilitación de escritura (W): Si W = 0 no se puede escribir sobre el segmento, mientras que si W = 1 se puede realizar la escritura.

    Si el bit 3 vale uno:
    • Bit 2: Conforme (C): Si C = 1, el segmento de código sólo puede ser ejecutado si CPL es mayor que DPL y CPL no cambia. Los segmentos conformes sirven para rutinas del sistema operativo que no requieran protección, tales como rutinas matemáticas, por ejemplo.

    • Bit 1: Habilitación de lectura (R): Si R = 0, el segmento de código no se puede leer, mientras que si R = 1 sí. No se puede escribir sobre el segmento de código.

  • Bit 0: Accedido (A): Si A = 0 el segmento no fue accedido, mientras que si A = 1 el selector se ha cargado en un registro de segmento o utilizado por instrucciones de test de selectores. Este bit es puesto a uno por el microprocesador.

     

Si se lee o escribe en un segmento donde no está permitido o se intenta ejecutar en un segmento de datos se genera una excepción 13 (Violación general de protección). Si bien no se puede escribir sobre un segmento de código, éstos se pueden inicializar o modificar mediante un alias. Los alias son segmentos de datos con permiso de escritura (E = 0, W = 1) cuyo rango de direcciones coincide con el segmento de código.

Los segmentos de código cuyo bit C vale 1, pueden ejecutarse y compartirse por programas con diferentes niveles de privilegio (ver la sección sobre protección, más adelante).

A continuación se verá el formato del byte de derechos de acceso para descriptores de segmentos del sistema:

 

  • Bit 7: Presente (P): Igual que antes.

  • Bits 6 y 5: Nivel de privilegio del descriptor (DPL): Igual que antes.

  • Bit 4: Bit descriptor del segmento (S): Como se explicó más arriba, este bit vale 0 para descriptores del sistema.

     

  • Bits 3-0: Tipo de descriptor: En el 80286 están disponibles los siguientes:

     

    0000: Inválido

    0100: Compuerta de llamada

    0001: TSS disponible

    0101: Compuerta de tarea

    0010: LDT

    0110: Compuerta de interrupción

    0011: TSS ocupado

    0111: Compuerta de trampa

    Los otros ocho tipos están reservados para el procesador 80386 y posteriores.

     

Como se pudo observar hay atributos en común entre los distintos descriptores: P, DPL y S.

Ahora se verá con más detalle los diferentes descriptores del sistema.

 

  • Descriptores de LDT (S = 0, tipo = 2): Contienen información sobre tablas de descriptores locales. Las LDT contienen una tabla de descriptores de segmentos, únicos para cada tarea. Como la instrucción para cargar el registro LDTR sólo está disponible en el nivel de privilegio 0 (nivel más privilegiado), el campo DPL es ignorado. Los descriptores de LDT sólo se permiten en la tabla de descriptores globales (GDT).

     

  • Descriptores de TSS (S = 0, tipos = 1, 3): Un descriptor de segmento de estado de la tarea (TSS: Task State Segment) contiene información sobre la ubicación, el tamaño y el nivel de privilegio de un TSS. Un TSS es un segmento especial con formato fijo que contiene toda la información sobre el estado de una tarea y un campo de enlace para permitir tareas anidadas. El campo de tipo se usa para indicar si la tarea está ocupada (tipo = 3), es decir, en una cadena de tareas activas, o si el TSS está disponible (tipo = 1). El registro de tarea (TR: Task Register) contiene el selector que apunta al TSS actual dentro de la GDT.

     

  • Descriptores de compuertas (tipos = 4 a 7): Las compuertas se utilizan para controlar el acceso a puntos de entrada dentro del segmento de código objetivo. Los distintos tipos de compuerta son: de llamada (call gate), de tarea (task gate), de interrupción (interrupt gate) y de trampa (trap gate). Las compuertas proveen un nivel de indirección entre la fuente y el destino de la transferencia de control. Esta indirección permite al procesador realizar automáticamente verificaciones de protección. También permite a los diseñadores controlar los puntos de entrada a los sistemas operativos. Las compuertas de llamada se utilizan para cambiar niveles de privilegio (ver la sección que trata sobre privilegio, más adelante), las compuertas de tarea se utilizan para hacer cambios de tarea y las de interrupción y de trampa se utilizan para especificar rutinas de servicio de interrupción.

3.3.5 PREFIJO PARA CAMBIO DE SEGMENTOS

bottom of page