Я могу рассказать вам, как это работает на x86.
Все программы в не 64-битных режимах работают с адресами, объединенными из двух элементов: segment selector
(для краткости «селектор» часто опускается в тексте, что может сбивать с толку) и offset
. Эта пара selector:offset
называется logical address
.
Селекторная часть не всегда явно указывается или обрабатывается в коде, поскольку ЦП имеет ассоциации по умолчанию «сегментных регистров», содержащих селекторы с конкретными инструкциями или конкретными кодировками команд. Также необычно манипулировать селекторами в 32-битном режиме, но очень часто необходимо в 16-битном коде.
virtual address
формируется из логического адреса «напрямую» (в режиме real
или 8086 virtual
) или «косвенно» (в режиме protected
).
"Direct" virtual address
= selector
* 16 + offset
.
"Indirect" virtual address
= SegmentDescriptorTable [selector
]. База + offset
.
SegmentDescriptorTable - это либо Global Descriptor Table
(AKA GDT
), либо таблица локальных дескрипторов (AKA LDT
). Он устанавливается ОС и описывает расположение и размер различных сегментов памяти. selector
используется для выбора сегмента в таблице. Запись Base
таблицы указывает начало сегмента (виртуальный адрес). Запись Limit
указывает размер сегмента (обычно детали более сложные).
Когда программа пытается получить доступ к памяти со смещением, результатом которого является доступ за концом сегмента (ЦП сравнивает offset
и Limit
), ЦП генерирует exception
и ОС обрабатывает его, обычно завершая программа.
Между прочим, в режиме real/v86
, хотя виртуальный адрес формируется непосредственно из selector:offset
, для смещений по-прежнему применяется 16-разрядный Limit
, поэтому для доступа к большему количеству необходимо использовать другой селектор. 64 КБ памяти.
Запись Base
в дескрипторе сегмента может использоваться, чтобы либо изолировать сегмент от остальной памяти (здесь помогает Limit
), либо поместить или переместить весь сегмент на произвольный виртуальный адрес без необходимости изменения все (или многое) в программе, к которой он принадлежит (если мы перемещаем сегмент, данные должны быть перемещены в памяти, очевидно). По сути, он может быть использован для целей перемещения. В режиме real/v86
для целей перемещения selector
изменяется.
virtual address
может быть дополнительно переведен в physical address
, если процессор работает в protected mode
и настроил page tables
. Если таблиц страниц нет, физический адрес совпадает с виртуальным адресом. Перевод выполняется в блоках физической памяти и диапазонах адресов, которые называются pages
(часто 4 КБ).
На процессорах x86 нет выделенного регистра перемещения. Перемещение может быть достигнуто путем настройки:
- селекторы сегментов в регистрах процессора или кода программы
- сегменты базовых адресов в GDT / LDT
- смещения в коде программы
- физические адреса в таблицах страниц
Что касается virtual address : reside in the hard disk , as a pages
, я не уверен, что именно вы хотите сказать по этому поводу, но только потому, что существует виртуальная трансляция адресов, это не означает, что есть также виртуальная память на диске. Есть и другие способы использования перевода, кроме виртуальной памяти на диске. А адреса находятся в ЦП и везде, куда ваш (и ОС) код записывает их, не обязательно на диск.