Процессор работает с виртуальными адресами, а железо памяти — с физическими. Между ними стоит таблица страниц, которая для каждой виртуальной страницы хранит номер физического кадра. Твоя задача — реализовать перевод одного виртуального адреса в физический через простую одноуровневую таблицу страниц.
Подробнее про сам механизм — в главе Страничная организация памяти.
func Translate(va int, table []int, pageSize int) (int, bool)
va — виртуальный адрес (целое, неотрицательное).
table — таблица страниц. table[i] — номер физического кадра для виртуальной страницы i. Если значение < 0, запись считается невалидной (страница не отображена).
pageSize — размер страницы в байтах, всегда степень двойки (например, 16, 4096).
Возвращает (физический адрес, true) при успехе или (0, false), если перевести адрес нельзя (page fault).
Виртуальный адрес делится на две части:
- номер страницы
vpn = va / pageSize
- смещение внутри страницы
offset = va % pageSize
Если vpn выходит за границы таблицы или запись table[vpn] невалидна (< 0) — это page fault, верни (0, false). Иначе физический адрес собирается из номера кадра и того же смещения:
pa = table[vpn] * pageSize + offset
Пусть pageSize = 16 (значит, смещение занимает 4 младших бита) и table = []int{2, -1, 5}.
Переведём va = 35:
va = 35
vpn = 35 / 16 = 2 -> table[2] = 5 (валидно)
offset = 35 % 16 = 3
pa = 5 * 16 + 3 = 83
table := []int{2, -1, 5} // pageSize = 16
Translate(35, table, 16) // (83, true)
Translate(3, table, 16) // vpn=0, offset=3 -> 2*16+3 = 35, true
Translate(20, table, 16) // vpn=1 -> table[1] = -1 -> (0, false) // page fault
Translate(48, table, 16) // vpn=3 -> за пределами таблицы -> (0, false)
- Пустая таблица
[]int{} — любой адрес даёт (0, false).
vpn ровно за последней записью таблицы — page fault.
offset на границе страницы (va % pageSize == pageSize-1) — обычный валидный адрес, не путать с переходом на следующую страницу.
- Номер кадра может быть
0 — это валидная запись (а не «пусто»), невалидна только запись < 0.