Далее используются термины и размеры из i386, что типично для архитектуры таблицы с прямым отображением страниц. Приведенный ниже код иллюстрирует шаги, которые процессор выполняет для получения виртуального адреса:
typedef struct {
unsigned valid:1, perm:11, paddr:20;
} pte;
unsigned pg_offset(va) { return va & 4095; }
unsigned lo_index(va) { return (va >> 12) & 1023; }
unsigned hi_index(va) { return (va >> 22) & 1023; }
paddr_t vtop(va) {
pte temp, *pte;
pte = (pte *)GetCr3();
temp = pte[hi_index(va)];
if (temp.valid /* other checks too */) {
pte = (pte *)(temp.paddr * 4095);
temp = pte[lo_index(va)];
if (temp.valid /* other checks too */) {
return temp.paddr * 4095 + pg_offset(va);
}
}
raise_pagefault_exception();
}
Итак, в ваших вопросах: смещение не равно 2c, потому что это смещение, примененное к окончательному переводу;тот, на который вы указываете, является первым переводом, который использует только биты 22..31 из va.
Старшие биты адреса выбирают запись 1 из таблицы, физический адрес которой равен 1,не 3. 3 не имеет никакого отношения к этому переводу.
P, вероятно, относится к настоящему (или действительному), указывающему, что эта запись таблицы страниц действительна.
Потому что это то, что индексыс адреса производят;если бы это был другой адрес, он мог бы создать другие индексы. Автор книги мог бы сделать гораздо лучший пример, возможно, с некоторыми отчетливыми показателями. Однажды ты можешь стать лучше.