< Назад  Далее >

Статья 5. Сегментная адресация и сегментная структура программ

Почему программа должна обязательно состоять из сегментов? Причина этого кроется в архитектурных особенностях микропроцессоров корпорации Intel, которые нам придется здесь коротко рассмотреть. Важнейшей характеристикой любого микропроцессора (МП) является разрядность его внутренних регистров, а также внешних шин адресов и данных. МП Intel 8086 имеет 16-разрядную внутреннюю архитектуру и такой же разрядности шину данных. Таким образом, максимальное целое число (данное или адрес), с которым может работать микропроцессор, составляет 216–1 = 65535 (64К–1). Однако адресная шина МП 8086 содержит 20 линий, что соответствует адресному пространству 220 = 1 Мбайт. Для того, чтобы с помощью 16-разрядных адресов можно было обращаться в любую точку 20-разрядного адресного пространства, в микропроцессоре предусмотрена сегментная адресация памяти, реализуемая с помощью четырех сегментных регистров.

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

Рис. 5.1. Образование физического адреса из сегментного адреса и смещения

Рис. 5.1. Образование физического адреса из сегментного адреса и смещения


Современные 32-разрядные процессоры Intel, в частности, процессоры Pentium, имеют 32-разрядную адресную шину, что соответствует адресному пространству 232= 4 Гбайт. Однако описанный выше способ сегментной адресации памяти не позволяет выйти за пределы 1 Мбайт. Для преодоления этого ограничения в 32-разрядных процессорах используются два режима работы: реального адреса (реальный режим) и виртуального защищенного адреса (защищенный режим). В реальном режиме процессор функционирует фактически так же, как МП 8086 с повышенным быстродействием и может обращаться лишь к 1 Мбайт адресного пространства. Оставшаяся память, даже если она установлена на компьютере, использоваться не может.

В защищенном режиме по-прежнему используются сегменты и смещения в них, однако начальные адреса сегментов не вычисляются путем умножения на 16 содержимого сегментных регистров, а извлекаются из таблиц сегментных дескрипторов, индексируемых с помощью тех же сегментных регистров. Каждый сегментный дескриптор занимает 8 байт, из которых 4 байт (32 бит) отводятся под сегментный адрес. Тем самым обеспечивается полное использование 32-разрядного адресного пространства. В этом случае микропроцессор позволяет адресовать до 232= 4 Гбайт физической памяти. Программирование защищенного режима будет подробно рассмотрено в следующей части этой книги.

Итак, обращение к любым участкам памяти осуществляется исключительно посредством сегментов — логических образований, накладываемых на требуемые участки физического адресного пространства. Размер сегмента должен находиться в пределах 0 байт – 64 Кбайт (допустимы и иногда используются сегменты нулевой длины). Начальный адрес сегмента, деленый на 16, т.е. без младшей шестнадцатиричной цифры, заносится (как правило, программистом с помощью соответствующих программных строк) в один из сегментных регистров. При обращении к памяти процессор извлекает из сегментного регистра этот базовый адрес, умножает его на 16 и складывает с заданным каким-либо образом смещением, получая 20-разрядный физический адрес адресуемой ячейки памяти (слова или байта). Этот процесс проиллюстрирован на рис. 5.2 на конкретном примере команды inc mem1.

Рис. 5.2. Формирование физического адреса

Рис. 5.2. Формирование физического адреса


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

Наличие в микропроцессоре четырех сегментных регистров определяет структуру программы. В типичной, не слишком сложной программе имеются сегмент команд, сегмент данных и сегмент стека, которые адресуются с помощью сегментных регистров CS, DS и SS соответственно. Дополнительный сегментный регистр ES часто используется для обращения к полям данных, не входящим в программу, например к видеобуферу или системным ячейкам. Однако при необходимости его можно настроить и на один из сегментов программы. В частности, если программа работает с большим объемом данных, для них можно предусмотреть два сегмента и обращаться к одному из них через регистр DS, а к другому — через ES.

Наша первая программа из статьи 1 содержала лишь один сегмент, в котором располагались и команды, и данные. Такая конструкция программы вполне законна, но не очень наглядна. Кроме того, предусмотрев в программе лишь один сегмент, мы ограничили суммарный объем команд и данных величиной 64К. Разумнее разнести команды и данные по отдельным сегментам, что продемонстрировано в примере 5.1.


Пример 5.1. Программа с двумя сегментами


text     segment 'code'  ; (1) Начало сегмента команд
         assume CS:text, DS:data ; (2) Регистр CS будет указывать на
                         ; сегмент команд, DS - на сегмент данных
begin:   mov    AX,data  ; (3) Адрес сегмента данных загрузим
         mov    DS,AX    ; (4) сначала в AX, затем в DS
         mov    AH,9     ; (5) Функция DOS вывода на экран
         mov    DX,offset message ; (6) Адрес выводимого сообщения
         int    21h      ; (7) Вызов DOS
         mov    AX,4C00h ; (8) Функция 4Ch и код завершения 0
         int    21h      ; (9) Вызов DOS
text     ends            ; (10) Конец сегмента команд
data     segment         ; (11) Начало сегмента данных
message  db     'Наука умеет много гитик$' ; (12) Выводимый текст
data     ends            ; (13) Конец сегмента данных
         end    begin    ; (14) Конец текста с точкой входа

Приведенная программа отличается от примера 1.1 лишь несколькими деталями (хотя ее структура, можно сказать, отличается радикально). Вслед за сегментом команд введен отдельный сегмент данных с произвольным именем data. Этот сегмент открывается в предложении 11 и закрывается в предложении 13. Изменилось предложение 2 — в нем указано, что сегментный регистр CS будет указывать на сегмент команд text, а регистр DS — на сегмент данных data. Соответственно изменилось и предложение 3. Теперь в регистр DS загружается адрес сегмента данных data, а не сегмента команд text, как это было в примере 1.1.

Оттранслировав, скомпоновав и выполнив программу примера 5.1, можно заметить, что результат работы этой программы в точности тот же, что и для первой, односегментной программы. Действительно, введение отдельного сегмента данных повысило наглядность программы и дало нам возможность (которой мы пока не воспользовались) увеличить общий размер программы до 128 Кбайт (64 Кбайт команд и 64 Кбайт данных). Однако существо программы осталось без изменения.

Теперь у нас есть две простых программы, одна с одним сегментом, а другая — с двумя. Запустите первую программу (пример 1.1) под управлением отладчика, выясните, чему равен сегментный адрес сегмента команд и определите, в какое место оперативной памяти загружена программа. Проследите за процессом настройки сегментного регистра DS. Обратите внимание на то, что перед началом выполнения программы содержимое регистров DS и ES оказывается в точности на 10h меньше содержимого регистра CS. В дальнейшем этот важный факт получит свое объяснение. Запустите под управлением отладчика вторую программу (пример 5.1), изучите расположение сегментов программы в памяти, сопоставьте полученные результаты с размерами сегментов, полученными из листинга трансляции.


Сайт управляется системой uCoz