1. Repaso: paginación
La memoria virtual se divide en páginas y la física en marcos del mismo tamaño (tema 18). La MMU traduce cada dirección virtual a física usando la tabla de páginas del proceso. La traducción tiene dos pasos: dividir la dirección virtual en página y desplazamiento, y luego buscar el marco en la tabla.
2. Dividir la dirección: p y d
Para una dirección virtual v y un tamaño de página P (potencia de 2):
p = v / P (división entera) · d = v mod P (resto)
Como P es potencia de 2, esto equivale a tomar los bits altos (p) y los bits bajos (d). Si la página es de 2k bytes, los k bits menos significativos son el desplazamiento y el resto el número de página.
Ejemplo: P = 4096 = 212. Los 12 bits bajos son el desplazamiento (0 a 4095), los bits restantes el número de página.
3. Cálculo con distintos tamaños
| Tamaño de página | Bits del desplazamiento | Máscara (hex) | Rango del desplazamiento |
|---|---|---|---|
| 256 B (28) | 8 | 0xFF | 0x00 – 0xFF |
| 1024 B (210) | 10 | 0x3FF | 0x000 – 0x3FF |
| 4096 B (212) | 12 | 0xFFF | 0x000 – 0xFFF |
| 8192 B (213) | 13 | 0x1FFF | 0x0000 – 0x1FFF |
La máscara se obtiene como P - 1. El número de página es v >> k (desplazamiento a la derecha) y el desplazamiento es v & (P - 1).
4. Ejemplos resueltos a mano
Ejemplo 1: P = 4096, v = 0x3A7C.
- p = 0x3A7C / 0x1000 = 3.
- d = 0x3A7C % 0x1000 = 0xA7C.
Ejemplo 2: P = 1024, v = 0x2ABC.
- p = 0x2ABC / 0x400 = 10 (0xA).
- d = 0x2ABC % 0x400 = 0x2BC.
Ejemplo 3: P = 256, v = 0x01FF.
- p = 0x01FF / 0x100 = 1.
- d = 0x01FF % 0x100 = 0xFF.
5. Traducción completa: virtual → física
Una vez obtenida la página p, se busca el marco f en la tabla de páginas. La dirección física es:
Física = f × P + d
Ejemplo completo: P = 4096, tabla = {5, 2, 8, 1}, v = 0x2ABC.
- p = 0x2ABC / 0x1000 = 2.
- d = 0x2ABC % 0x1000 = 0xABC.
- f = tabla[2] = 8.
- Física = 8 × 4096 + 0xABC = 0x8000 + 0xABC = 0x8ABC.
6. Experimento en C
El programa siguiente calcula p y d para varias direcciones y tamaños de página:
#include <stdio.h>
void descomponer(unsigned int v, unsigned int P)
{
unsigned int p = v / P;
unsigned int d = v % P;
printf("v=0x%04X P=%u -> pagina=%u desp=0x%03X\\n", v, P, p, d);
}
int main(void)
{
unsigned int vs[] = {0x3A7C, 0x2ABC, 0x01FF, 0x0000, 0x0FFF, 0x1000};
unsigned int Ps[] = {4096, 1024, 256};
for (int j = 0; j < 3; j++)
for (int i = 0; i < 6; i++)
descomponer(vs[i], Ps[j]);
return 0;
}
$ gcc -std=c17 -Wall -Wextra -o traduccion traduccion.c
$ ./traduccion
v=0x3A7C P=4096 -> pagina=3 desp=0xA7C
v=0x2ABC P=4096 -> pagina=2 desp=0xABC
v=0x01FF P=4096 -> pagina=0 desp=0x1FF
v=0x0000 P=4096 -> pagina=0 desp=0x000
v=0x0FFF P=4096 -> pagina=0 desp=0xFFF
v=0x1000 P=4096 -> pagina=1 desp=0x000
v=0x3A7C P=1024 -> pagina=14 desp=0x27C
v=0x2ABC P=1024 -> pagina=10 desp=0x2BC
v=0x01FF P=1024 -> pagina=0 desp=0x1FF
v=0x0000 P=1024 -> pagina=0 desp=0x000
v=0x0FFF P=1024 -> pagina=3 desp=0xFFF
v=0x1000 P=1024 -> pagina=4 desp=0x000
v=0x3A7C P=256 -> pagina=58 desp=0x7C
v=0x2ABC P=256 -> pagina=42 desp=0xBC
v=0x01FF P=256 -> pagina=1 desp=0xFF
v=0x0000 P=256 -> pagina=0 desp=0x00
v=0x0FFF P=256 -> pagina=15 desp=0xFF
v=0x1000 P=256 -> pagina=16 desp=0x00v=0x1000 P=256 -> pagina=16 desp=0x00
7. Casos límite
- Dirección 0: página 0, desplazamiento 0. Siempre válida si la página 0 está presente.
- Último byte de una página: desplazamiento = P - 1 (ej. 0xFFF para 4096).
- Primera dirección de la siguiente página: desplazamiento 0, página incrementada.
- Dirección máxima: depende del tamaño del espacio virtual (248 en x86-64).
- Página no presente: la entrada de la tabla tiene el bit presente a 0 → fallo de página.
8. Probar con un simulador
Este simulador descompone una dirección virtual en página y desplazamiento para un tamaño de página dado, y traduce a física usando una tabla editable.
Simulador · traducción de direcciones
| Campo | Valor |
|---|---|
| Página (p) | |
| Desplazamiento (d) | |
| Marco (f) | |
| Dirección física |
Tabla de páginas (editable):
9. En Linux
En Linux, el tamaño de página es 4096 bytes por defecto. Las herramientas para observar la paginación:
$ getconf PAGESIZE
4096
$ python3 -c "print(hex(0x2ABC // 4096), hex(0x2ABC % 4096))"
$ cat /proc/self/maps | head -5
getconf PAGESIZE: tamaño de página.- El cálculo de página y desplazamiento se hace con división y módulo (o con bits).
/proc/PID/maps: muestra las regiones, no las páginas individuales.
10. Resumen
- La dirección virtual se divide en número de página (p) y desplazamiento (d).
- p = v / P, d = v mod P (o con bits si P es potencia de 2).
- La traducción completa: p → marco f, física = f × P + d.
- El desplazamiento se conserva; solo la página cambia.
- Casos límite: dirección 0, último byte de página, primera de la siguiente.
11. Preguntas de repaso
Intenta responder cada una antes de abrir la respuesta.
1. ¿Cómo se obtiene el número de página?
Dividiendo la dirección virtual por el tamaño de página (división entera).
2. ¿Cómo se obtiene el desplazamiento?
Calculando el resto de la división de la dirección virtual por el tamaño de página.
3. ¿Qué parte de la dirección no cambia en la traducción?
El desplazamiento (d): es el mismo en la página virtual y en el marco físico.
4. ¿Cuál es el desplazamiento máximo para una página de 4096 bytes?
4095 (0xFFF): los valores van de 0 a P-1.
5. ¿Qué es una página no presente?
Una página cuya entrada en la tabla tiene el bit presente a 0: no está en la RAM.
6. ¿Cómo se calcula la dirección física?
Física = marco × tamaño_de_página + desplazamiento.
7. ¿Por qué el tamaño de página es potencia de 2?
Para que la división y el módulo se puedan hacer con desplazamientos de bits (más rápido).
8. ¿Qué herramienta da el tamaño de página en Linux?
getconf PAGESIZE.
Para practicar
- Calcula p y d para las direcciones 0x5A3F, 0x1000 y 0x0FFF con página de 4096.
- Traduce 0x5A3F a física con tabla {2, 5, 1, 7, 3} (página 5 → marco 3).
- Modifica
traduccion.cpara que también calcule la dirección física dada una tabla. - Explica por qué el desplazamiento no cambia en la traducción.
- Calcula cuántas páginas tiene un proceso de 1 MiB con páginas de 4 KiB.
- Implementa la descomposición usando operaciones de bits (>> y &) en lugar de / y %.
- Dibuja la traducción de 0x2ABC paso a paso con tabla {3, 7, 1}.