Сегментная адресация в реальном режиме.
Реальный режим работы процессора это режим, в котором работало первое поколение процессоров (i8086, i8088), любой современный процессор после включения питания начинает работать в реальном режиме и только потом программно переводится в защищенный режим.
Для работы с памятью используются две шины - шина адреса и шина данных. Физически память устроена таким образом, что возможна адресация как 16-битовых слов, так и отдельных байтов памяти. Кроме того, процессоры начиная с i80386 могут адресовать 32-битовые слова памяти.
В любом случае так называемый физический адрес передаётся из процессора в память по шине адреса. Ширина шины адреса определяет максимальный объём физической памяти, непосредственно адресуемой процессором. Для 20-разрядной адресной шины процессора i8086 используется двадцать двоичных (или пять шестнадцатеричных) разрядов. Однако все регистры этого процессора являются 16-разрядными. Возникает проблема представления 20-разрядного физического адреса памяти при помощи содержимого 16-разрядных регистров. Максимальное число (данное или адрес), которое можно записать в 16-разрядный регистр, составляет всего 216 - 1 = 65535, или 64Кб-1 из нужного нам одного мегабайта.
Для разрешения этой проблемы используется двухкомпонентный логический адрес. Логический адрес состоит из двух 16-разрядных компонент. Такой способ называется сегментной адресацией памяти.
Суть сегментной адресации заключается в следующем. Обращение к памяти осуществляется исключительно с помощью сегментов. Сегментом называется условно выделенная область адресного пространства определённого размера. В реальном режиме процессора всё адресное пространство делится на одинаковые сегменты размером 64Кб.
Физический адрес любой ячейки памяти вычисляется процессором путем сложения начального адреса сегмента (базы сегмента), в котором располагается эта ячейка, со смещением к ней (в байтах) от начала сегмента (рис. 17). Это смещение иногда называют относительным адресом.
Рисунок 17 Образование физического адреса из сегментного адреса и смещения.
Покажем как вычисляется физический адрес – для получения 20-разрядного физического адреса к сегментной компоненте (заносящейся в сегментный регистр) приписывается справа четыре нулевых бита (для расширения до 20 разрядов), затем полученное число складывается с компонентой смещения. Перед сложением к компоненте смещения слева дописывается четыре нулевых бита (также для расширения до 20 разрядов). Эту процедуру иллюстрирует рисунок 18
Рисунок 18. Вычисление физического адреса в реальном режиме.
Логический адрес принято записывать в шестнадцатеричной форме в виде <сегмент : смещение>.
Например, пусть у нас есть логический адрес 1234h:0123h. Содержимое базового регистра равно 1234h, регистра смещения - 0123h. Вычислим физический адрес, соответствующий нашему логическому адресу:
1. расширяем до 20 бит сегментную компоненту, дописывая справа 4 нулевых бита, получаем число 12340h;
2. расширяем до 20 бит компоненту смещения, дописывая слева 4 нулевых бита, получаем число 00123h;
3. для получения физического адреса складываем полученные числа: 12340h + 00123h = 12463h.
Очевидно, что одному физическому адресу может соответствовать несколько логических. Например, физическому адресу 12463h соответствует логический адрес 1246h:0003h.
Фактически в схеме адресации памяти реального режима вся память как бы разбивается на перекрывающиеся сегменты размером 64Кб. Физический адрес начала сегмента (базовый адрес) равен расширенной до 20 бит сегментной компоненте адреса (расширение выполняется дописыванием справа 4 нулевых бит).
Сегмент может начинаться не с любого физического адреса, а только с такого, который кратен 16 байтам. Деление адресного пространства на фрагменты по 16 байт с которых может начинаться сегмент называется делением на параграфы, поэтому обычно говорят, что сегмент может начинаться только с границы параграфа.
Содержимое сегментного регистра при такой схеме адресации определяет номер сегмента, а компонента смещения является смещением внутри сегменты памяти. Рисунок 19 иллюстрирует сказанное выше.
Рисунок 19. Соответствие логического и физического адресов.
На этом рисунке показано соответствие логического адреса 0002h:0028h физическому адресу 00048h.
Использование сегментной адресации дает дополнительное преимущество при программировании.
Каждой программе выделяется свой собственный сегмент (или даже несколько). Внутри каждого сегмента начинается собственная адресация от нуля - смещение. Таким образом, программист во время кодирования может вообще не заботиться, где именно физически будет размещена программа в памяти.
Операционная система управляет загрузкой и выгрузкой программ примерно так. Свободный сегмент выделяется программе во время загрузки. А после того, как программа завершилась, операционная система снова помечает сегмент как незанятый.
Область верхней памяти (HMA)
Логический адрес должен находиться в следующих пределах:
0000h:0000h <= [логический адрес] <= FFFFh:000Fh
Здесь есть одна тонкость. Логический адрес FFFFh:000Fh соответствует максимально возможному физическому адресу FFFFFh. Но используя 16-разрядные регистры процессора можно задать и большее значение для логического адреса, например, FFFFh:0010h. Что произойдёт в этом случае?
Покажем как производиться сложение:
+ | F | F | F | F | ||
Если в компьютере установлены процессоры i8086 или i8088, произойдёт переполнение адреса, которое будет проигнорировано процессором. В результате 21-й бит теряется и, например, логический адрес FFFF:0010h указывает туда же, куда и адрес 0000:0000h, то есть на физический адрес 00000h.
Если же используются процессоры i80286 или старше, физическая шина адреса шире 20 бит. При работе в реальном режиме используются младшие 20 адресных линий - от A0 до A19, остальные адресные линии аппаратура компьютера блокирует.
Однако есть возможность снять блокировку с адресной линии A20. При этом в реальном режиме переполнения не происходит и появляется ещё одна «льготная» область памяти, лежащая выше границы первого мегабайта. Этот сегмент называется областью верхней или старшей памяти (High Memory Area, HMA). Ему соответствует диапазон адресов от FFFFh: 0010h = 100000h до FFFFh: FFFFh = 10FFEFh. Размер области старшей памяти составляет 64 килобайта без 16 байт.