Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции 2007.doc
Скачиваний:
117
Добавлен:
20.05.2014
Размер:
3.24 Mб
Скачать

Сегментная организация памяти.

Память может логически организовываться в виде одного или множества блоков, сегментов произвольной длины (в реальном режиме фиксированной). Мы уже говорили, что в защищенном режиме возможно разбиение логической памяти на страницы размером 4 Кбайт (до 5 Мбайт в современных процессорах), каждая из которых может отображаться на любую область физической памяти. Сегментация и страничная трансляция адресов могут применяться совместно и по отдельности. Сегментация является средством организации логической памяти на прикладном уровне, а страничная трансляция адресов на системном уровне.

Что бы лучше понять принцип сегментирования рассмотрим его на примере процессора Intel 8086. Вся память системы представляется не в виде непрерывного пространства, а в виде нескольких блоков — сегментов заданного размера (по 64 Кбайт), положение которых в пространстве памяти можно изменять программным путем. Для хранения кодов адресов памяти используются не отдельные регистры, а пары регистров:

  • сегментный регистр определяет адрес начала сегмента (база сегмента), то есть положение сегмента в памяти;

  • регистр указателя (регистр смещения) определяет положение рабочего адреса внутри сегмента.

При этом физический 20-разрядный адрес памяти, выставляемый на внешнюю шину адреса, образуется путем сложения смещения, и адреса сегмента со сдвигом на 4 бита. Сегмент может начинаться только на 16-байтной границе памяти (так как адрес начала сегмента, по сути, имеет четыре младших нулевых разряда, то есть с адреса, кратного 16. Эти допустимые границы сегментов называются границами параграфов. Отметим, что введение сегментирования, прежде всего, связано с тем, что внутренние регистры процессора 16-разрядные, а физический адрес памяти 20-разрядный (16-разрядный адрес позволяет использовать память только в 64 Кбайт, что явно недостаточно).

Чтобы лучше понять, как из двух 16 битовых слов получается 20 битовый адрес еще раз покажем это на двоичном примере.

Пусть имеется 2 машинных слова:

ABCDHи 1234H

(вспомним, что каждая 16-ричная цифра представляет 4 бита, например – 11112 = 1510=F16); Берем первое число и приписываем 0 справа (если больше нравится - умножаем на 16), получимABCD0, т.е. первоначальное число, но со смещением на один 16-ричный разряд. Это 20-ти разрядное число, но оно не может нам служить 20 битовым адресом, т.к. оно заканчивается на нуль и, следовательно, может представлять только адреса которые тоже заканчиваются на нуль. Другими словами оно пригодно для адресации каждого 16-го байта или сегмента.

A*164+B*163+C*162+D*161+ 0*160

При изменении A,B,C,Dизменяется дискретно сегмент (параграф).

Чтобы получить окончательную схему сегментированной адресации возьмем другое 16-ти битовое число – 1234 Hи сложим его с модифицированным первым:

ABCD0

+ 1234

----------------

получим ACF04 двадцати битовое число, которое может принимать любые значения от 0 до 1 048 577

Таким образом, ABCD0 – сегментная часть, которая указывает на ту область адреса которая кратна 16 (сегмент, параграф). Второе число 1234 – смещение, которое указывает конкретное расположение байта внутри сегментного параграфа (это дает 65536 или 64 Кбайт адресов внутри сегмента). Поскольку эти составляющие перекрываются, конечный адрес можно получить различными способами:

D000:7FFF=D000 (сегмент)

+ 7FFF(смещение)

-----------

D7FFF(полный адрес)

Отметим, что линейный адрес является пятиразрядным, хотя мы использовали для сегмента и смещения четырехразрядные числа. Можно констатировать, что вычисление сегментированного адреса основано на так называемом сегментном сложении, позволяющем получить (например) 20-битовое двоичное число из двух 16 битовых.

Таким образом, мы смогли адресоваться к каждой ячейке 64 Кбайтового блока из почти 1 Мбайт объема общей памяти, используя только 16 разрядную шину адреса, а не 20 разрядную, как это было бы в случае прямой адресации.

Данные

Смещение

Базасегмента

ПАМЯТЬ

FFFFFH

16 битное расстояние

от базы – смещение

15 0 64 Кбайт

Адрес сегмента

16 байт 1 Мбайт

15 0 00000H

Рис. 8.4 Сегментная память процессора 8086

Для обращения к нужной ячейке памяти надо задать базу сегмента и 16-битное расстояние от базы называемое смещением или относительным адресом. Преобразование пары сегмент/смещение (наз. также виртуальным адресом) в физический адрес довольно простое: пусть регистр DSсодержит 1234H, а регистрSIсодержит 5678H, тогда физический адрес в командеMOVAX(загрузить слово в регистрAX) будет

DSx16 +SI= 12340H+ 5678H= 179B8H

Базовые адреса четырех одновременно доступных программе сегментов находятся в сегментных регистрах:

  • регистр команд – CS;

  • регистр данных – DS;

  • стека – SS

  • регистр дополнительных данных – ES.

Каждый из них 16-ти битовый, но можно считать, что они 20-ти разрядные.

Обратите внимание на магическую цифру 64 Кбайт, это объем памяти внутри которого адресация осуществляется с помощью неизменного значения сегментного регистра, т.е. внутри сегмента реализуется линейно адресуемая память.

Применяются и более сложные методы сегментированияпамяти. Например, в процессоре Intel 80286 в так называемом защищенном режиме адрес памяти вычисляется в соответствии с рис. 7.7. В сегментном регистре в данном случае хранится не базовый (начальный) адрес сегментов, а коды селекторов, определяющие адреса в памяти, по которым хранятся дескрипторы (то есть описатели) сегментов. Область памяти с дескрипторами называется таблицей дескрипторов. Каждый дескриптор сегмента содержит базовый адрес сегмента, размер сегмента (от 1 до 64 Кбайт) и его атрибуты. Базовый адрес сегмента имеет разрядность 24 бит, что обеспечивает адресацию 16 Мбайт физической памяти.

Рис. 8.5  Адресация памяти в защищенном режиме процессора Intel 80286.

Таким образом, на сумматор, вычисляющий физический адрес памяти, подается не содержимое сегментного регистра, как в предыдущем случае, а базовый адрес сегмента из таблицы дескрипторов.

Еще более сложный метод адресациипамяти ссегментированиемиспользован в процессоре Intel 80386 и в более поздних моделях процессоров фирмы Intel. Этот метод иллюстрируется рис. 7.8. Адрес памяти (физический адрес) вычисляется в три этапа. Сначала вычисляется так называемыйэффективный адресEA(32-разрядный) путем суммирования трех компонентов: базы, индекса и смещения (Base, Index, Displacement), причем возможно умножение индекса на масштаб (Scale). Эти компоненты имеют следующий смысл:

EA = BASE + (INDEX*SCALE) + DISPLACEMENT

Здесь BASE– базовый адрес массива,INDEX– номер элемента,DISPLACEMENT– смещение внутри элемента. Массив может состоять из байтов, слов, двойных слов и учетверенных слов – это учитывается коэффициентомSCALE(1,2,34 или 8).

Рис. 8.6   Формирование физического адреса памяти процессора 80386 в защищенном режиме.

  • смещение — это 8-, 16- или 32-разрядное число, включенное в команду.

  • база — это содержимое базового регистра процессора. Обычно оно используется для указания на начало некоторого массива.

  • индекс — это содержимое индексного регистра процессора. Обычно оно используется для выбора одного из элементов массива.

  • масштаб — это множитель (он может быть равен 1, 2, 4 или 8), указанный в коде команды, на который перед суммированием с другими компонентами умножается индекс. Он используется для указания размера элемента массива.

Затем специальный блок сегментации вычисляет 32-разрядный линейный адрес, который представляет собой сумму базового адреса сегмента из сегментного регистра с эффективным адресом. Наконец, физический 32-битный адрес памяти образуется путем преобразования линейного адреса блоком страничной переадресации, который осуществляет перевод линейного адреса в физический страницами по 4 Кбайт. В любом случае сегментированиепозволяет выделить в памяти один или несколько сегментов для данных и один или несколько сегментов для программ. Переход от одного сегмента к другому сводится всего лишь к изменению содержимого сегментного регистра. Иногда это бывает очень удобно. Но для программиста работать с сегментированной памятью обычно сложнее, чем с непрерывной, несегментированной памятью, так как приходится следить за границами сегментов, за их описанием, переключением и т.д.