Сегментная адресация и сегментная структура программ
Архитектурные особенности микропроцессоров корпорации Intel обусловливают сегментную организацию программ. Важнейшей характеристикой любого процессора является разрядность его внутренних регистров, а также внешних шин адресов и данных. МП 86 имеет 16-разрядную внутреннюю архитектуру и такой же разрядно- сти шину данных. Таким образом, максимальное целое число (данное или адрес), с которым может работать микропроцессор, составляет 216-1 = 65 535 (64 К - 1). Однако адресная шина МП 86 содержит 20 линий, что соответствует адресному пространству 220 =1 Мбайт. Для того чтобы с помощью 16-разрядных адресов можно было обращаться в любую точку 20-разрядного адресного пространства, в процессоре предусмотрена сегментная адресация памяти, реализуемая с помощью четырех сегментных регистров.
Суть сегментной адресации заключается в следующем. Физический 20-разрядный адрес любой ячейки памяти вычисляется процессором путем сложения 20-разрядного начального адреса сегмента памяти, в котором располагается эта ячейка, с 16- разрядным смещением к ней (в байтах) от начала сегмента (см.рис.). Начальный адрес сегмента без четырех младших бит, т. е. деленный на 16, хранится в одном из сегментных регистров. Эта величина называется сегментным адресом. Каждый раз при загрузке в сегментный регистр сегментного адреса процессор автоматически умножает его на 10h=16 и полученный таким образом базовый адрес сегмента сохраняет в одном из своих внутренних регистров. При необходимости обратиться к той или иной ячейке памяти процессор прибавляет к этому базовому адресу смещение ячейки, в результате чего образуется физический адрес ячейки в памяти. Умножение 16-разрядного сегментного адреса - 64 Кбайт на 16 увеличивает диапазон адресуемых ячеек до величины 1 Мбайт.
Современные 32-разрядные процессоры Intel, в частности процессоры Pentium, имеют 32-разрядную адресную шину, что соответствует адресному пространству 232 = = 4 Гбайт. Однако описанный выше способ сегментной адресации памяти не позволяет выйти за пределы 1 Мбайт. Для преодоления этого ограничения в 32-разрядных процессорах используются два режима работы: реальный и защищенный. В реальном режиме процессор функционирует фактически так же, как МП 86 с повышенным быстродействием, и может обращаться лишь к 1 Мбайт адресного пространства. Оставшаяся память, даже если она установлена на компьютере, использоваться не может.
В защищенном режиме по-прежнему используются сегменты и смещения в них, однако начальные адреса сегментов не вычисляются путем умножения на 16 содержимого сегментных регистров, а извлекаются из таблиц сегментных дескрипторов, индексируемых с помощью тех же сегментных регистров. Каждый сегментный дескриптор занимает 8 байт, из которых 4 байта 32 бита) отводятся под сегментный адрес. Тем самым обеспечивается полное использование 32-разрядного адресного простран- ства. В этом случае процессор позволяет адресовать до 232=4 Гбайт физической памяти.
Итак, в МП 86 обращение к любым участкам памяти осуществляется исключительно посредством сегментов - логических образований, накладываемых на требуемые участки физического адресного пространства. Размер сегмента должен находиться в пределах 0 байт ... 64 Кбайт (допустимы и иногда используются сегменты нулевой длины). Начальный адрес сегмента, деленный на 16, т. е. без младшей 16-ричной цифры, заносится (как правило, программистом с помощью соответствующих предложений программы) в один из сегментных регистров. Смещение же адресуемой ячейки указывается тем или иным образом в команде. Процесс адресации памяти проиллюстрируем на примере конкретной команды inc meml. Если предположить, что ячейка meml находится в байтах 4-5 сегмента данных, то полный код команды inc meml займет 4 байта и составит такую последовательность 16-ричных чисел:
FF 06 04 00
В этой последовательности первые 2 байта представляют собой код операции (выполнить инкремент над словом памяти), а вторые два - смещение в сегменте данных к адресуемой ячейке.
Поскольку младшая 16-ричная цифра базового адреса сегмента оказывается равной нулю, сегмент всегда начинается с адреса, кратного 16, т. е. на границе 16-байтового блока памяти (параграфа). Следует помнить, что сегментный адрес в 16 раз меньше соответствующего ему физического адреса памяти.
Наличие в микропроцессоре четырех сегментных регистров определяет структуру программы. В типичной, не слишком сложной программе имеются сегмент команд, сегмент данных и сегмент стека, которые адресуются с помощью сегментных регистров CS, DS и SS соответственно. Дополнительный сегментный регистр ES часто используется для обращения к полям данных, не входящим в программу, например к видеопамяти или системным ячейкам. Однако при необходимости его можно настроить и на один из сегментов программы. В частности, если программа работает с большим объемом данных, для них можно предусмотреть два сегмента и обращаться к одному из них через регистр DS, а к другому - через ES.
Язык ассемблера имеет, в частности, то преимущество, что программа, загруженная в память, полностью повторяет по своей структуре и порядку элементов исходный текст, написанный программистом. Так, если в сегменте данных последовательно описаны некоторые данные, они будут расположены в памяти в точности в том же порядке. Сами сегменты также размещаются в памяти в том порядке, в каком они следуют в исходном тексте.