Uso de registros de segmentación.

Estoy tratando de entender cómo la gestión de la memoria pasa a bajo nivel y tengo un par de preguntas.

1) Un libro sobre lenguaje ensamblador realizado por Kip R. Irvine dice que en el modo real, los primeros registros de tres segmentos se cargan con direcciones base de código, datos y segmento de pila cuando se inicia el programa. Esto es un poco ambiguo para mí. ¿Se especifican estos valores manualmente o el ensamblador genera instrucciones para escribir los valores en los registros? Si sucede automáticamente, ¿cómo averigua cuál es el tamaño de estos segmentos?

2) Sé que Linux usa un modelo lineal plano, es decir, usa la segmentación de una manera muy limitada. Además, según "Understanding the Linux Kernel" de Daniel P. Bovet y Marco Cesati, hay cuatro segmentos principales: datos de usuario, código de usuario, datos de kernel y código de kernel en GDT. Los cuatro segmentos tienen el mismo tamaño y dirección base. No entiendo por qué hay necesidad en cuatro de ellos si difieren solo en tipo y derechos de acceso (todos producen la misma dirección lineal, ¿no?). ¿Por qué no usar solo uno de ellos y escribir su descriptor en todos los registros de segmento?

3) ¿Cómo los sistemas operativos que no usan la segmentación dividen los programas en segmentos lógicos? Por ejemplo, cómo diferencian la pila del código sin descriptores de segmento. Leí que la paginación se puede usar para manejar esas cosas, pero no entiendo cómo.

Respuestas a la pregunta(3)

Su respuesta a la pregunta