Распределение адресного пространства
В зависимости от модификации персонального компьютера и состава его периферийного оборудования распределение адресного пространства может несколько различаться. Тем не менее, размещение основных компонентов системы довольно строго унифицировано. Типичная схема использования адресного пространства компьютера приведена на рис. 1.1. Значения адресов на этом рисунке, как и повсюду далее в книге, даны в 16-ричной системе счисления. Признаком 16-ричного числа служит буква h, стоящая после числа.
1 Кбайт Векторы прерываний 00000h
256 байтов Область данных BIOS 00400h
512 байтов Область данных DOS 00500h
IO.SYS/MSDOS.SYS 00700h Стандартная память
Загружаемые драйверы (640 Кбайт)
COMMAND.COM
|
Свободная память память(EMS)
для загружаемых
прикладных и системных
программ А0000h
64 Кбайт Графический буфер EGA B0000h
32 Кбайт UMB B8000h
32 Кбайт Текстовый буфер EGA C0000h Верхняя память(384 Кбайт)
64 Кбайт ПЗУ-расширения BIOS D00000h
64 Кбайт UMB E00000h
128 Кбайт ПЗУ BIOS 1000000h
64 Кбайт HMA 10FFF0h
До 15 Мбайт
(80286) XMS Расширенная память
До 4 Гбайт
(80386/486)
Первые 640 Кбайт, адресного пространства с адресами от OOOOOh до 9FFFFh отводятся под основную оперативную память, которую еще называют стандартной (conventional). Начальный килобайт оперативной памяти занят векторами прерываний (256 векторов по 4 байта). Вслед за векторами прерываний располагается область данных BIOS, которая занимает
адреса от 00400h до 004FFh. В этой области хранятся разнообразные данные, используемые программами BIOS в процессе управления периферийным оборудованием. Так, здесь размещаются:
- входной буфер клавиатуры с системой указателей;
- адреса последовательных и параллельных портов;
- данные, характеризующие настройку видеосистемы (форма курсора и его текущее местоположение на экране, текущий видеорежим, ширина экрана и прочее);
- ячейки для отсчета текущего времени;
- область межзадачных связей и т.д.
Область данных BIOS заполняется информацией в процессе начальной загрузки компьютера и динамически модифицируется системой по мере необходимости; многие прикладные программы обращаются к этой области с целью чтения или модификации содержащейся в ней информации.
В области памяти, начиная с адреса 500h, содержатся некоторые системные данные DOS. Вслед за областью данных DOS располагается собственно операционная система, загружаемая из файлов IO.SYS и MSDOS.SYS (1ВМВЮ.СОМ и IBMDOS.COM для системы PC-DOS). Система обычно занимает несколько десятков Кбайт.
Если в файл CONFIG.SYS включены директивы DEVICE=... загрузки устанавливаемых драйверов (ADM.SYS, SMARTDRV.SYS, EMM386.EXE, ANSI.SYS и др.), то они загружаются вслед за системой. Наконец, ниже драйверов размещается резидентная часть командного процессора COMMAND.COM, занимающая около 3 Кбайт. В функции резидентной части COMMAND.COM входит обработка <Ctrl>/C, <Ctrl>/<Break> и критических ошибок, вывод сообщений об ошибках, завершение текущей задачи, загрузка транзитной части COMMAND.COM. Транзитная, загружаемая часть COMMAND.COM размещается в самом конце оперативной памяти, затирается при загрузке программ и после завершения выполняемой программы должна загружаться с диска заново.
Перечисленные выше компоненты операционной системы занимают обычно 60-90 Кбайт. Вся оставшаяся память до границы 640 Кбайт (называемая иногда транзитной областью) свободна для загрузки любых системных или прикладных программ. Как правило, в начале сеанса в память загружают резидентные программы (русификатор, электронный блокнот, резидентные расширения DOS, программы контроля состояния диска, входящие, например, в состав Нортоновских утилит и др.). При наличии резидентных программ объем свободной памяти уменьшается. Оставшиеся 384 Кбайт адресного пространства, называемого верхней (upper) памятью, первоначально были предназначены для размещения постоянных запоминающих устройств (ПЗУ). Практически под ПЗУ занята только часть адресов. В самом конце адресного пространства, в области FOOOOh...FFFFFh (или EOOOOh... FFFFFh) располагается основное постоянное запоминающее устройство BIOS, а начиная с адреса COOOOh - так называемое ПЗУ расширений BIOS для обслуживания графических адаптеров и дисков. Часть адресного пространства верхней памяти отводится для адресации к видеобуферам графического адаптера. Приведенное на рисунке расположение видеобуферов характерно для адаптера EGA; для других адаптеров оно может быть иным, например, видеобуфер простейшего монохромного адаптера MDA занимает всего 4 Кбайт и располагается, начиная с адреса ВООООЮ.
В состав компьютеров PC/AT наряду со стандартной памятью (640 Кбайт) может входить расширенная (extended) память, максимальный объем которой зависит от ширины адресной шины процессора и при использовании процессора 80286 может достигать 15 Мбайт, а для процессоров 80386/486 - 4 Гбайт. Эта память располагается за пределами первого мегабайта адресного пространства и начинается с адреса lOOOOOh. Реально на машине может быть установлен не полный объем расширенной памяти, а лишь 2-3 Мбайт или даже меньше, например, всего 384 Кбайт.
Поскольку функционирование расширенной памяти подчиняется "спецификации расширенной памяти" (Extended Memory Specification, сокращенно XMS), то и саму память часто называют XMS-памятью. Как уже отмечалось выше, доступ к расширенной памяти осуществляется в защищенном режиме, поэтому для MS-DOS, работающей только в реальном режиме, расширенная память недоступна.
Однако в современные версии MS-DOS включается драйвер HIMEM.SYS, поддерживающий расширенную память, т.е. позволяющий ее использовать, хотя и ограниченным образом. Конкретно в расширенной памяти можно разместить электронные диски (с помощью драйвера RAMDRIVE.SYS) или кош буферы диска (с помощью драйвера SMARTDRV.SYS).
Первые 64 Кбайт расширенной памяти, точнее, 64 Кбайт -16 байт с адресами от lOOOOOh до lOFFEFh, носят специальное название область старшей памяти (High Memory Area, НМА). Эта область замечательна тем, что хотя она находится за пределами первого мегабайта, к ней можно обратиться в реальном режиме работы микропроцессора, если определить сегмент, начинающийся в самом конце мегабайтного адресного пространства. с ялпрся FFFFOh. и разрешить использование адресной линии А20. Первые 16 байтов этого сегмента заняты ПЗУ, область же со смещениями 0010h...FFFFh можно, в принципе, использовать под программы и данные. MS-DOS позволяет загружать в НМА (директивой файла CONFIG.SYS DOS=HIGH) значительную часть самой себя, в результате чего занятая системой, область стандартной памяти существенно уменьшается. Старшую память обслуживает тот же драйвер HIMEM.SYS, поэтому загрузка DOS и НМА возможна, только если установлен HIMEM.SYS.
Как видно из приведенного выше рисунка, часть адресного пространства верхней памяти, не занятая расширениями BIOS и видеобуферами, оказывается свободной. На компьютерах с МП 80386 и 80486 эти свободные участки можно использовать для адресации к расширенной памяти (конечно, не ко всей, а лишь к той ее части, объем которой совпадает с общим объемом свободных адресов верхней памяти). Пере отображение расширенной памяти на свободные адреса верхней памяти выполняет драйвер ЕММ386.ЕХЕ, а сами участки верхней памяти, "заполненные" расширенной, называются блоками верхней памяти (Upper Memory Blocks, UMB). MS-DOS позволяет загружать в UMB устанавливаемые драйверы устройств, а также резидентные программы-расширения DOS (APPEND.EXE, DOSKEY.COM, KEYB.COM и др.). Загрузка системных программ в UMB освобождает от них стандартную память, увеличивая ее транзитную область. В UMB можно загрузить также и прикладные резидентные программы. Загрузка в UMB драйверов осуществляется директивой файла CONFIG.SYS DEVICEHIGH (вместо директивы DEVICE), a загрузка резидентных программы - командой DOS LOADHIGH.
По умолчанию драйвер ЕММ386.ЕХЕ преобразует в UMB 128 Кбайт расширенной памяти, располагая ее по адресам СООО... CFFF. При необходимости (если, например, на эти адреса настроено какое-то нестандартное внешнее устройство) объем, и расположение UMB в адресном пространстве верхней памяти можно изменить с помощью ключей в строке установки драйвера ЕММ386.ЕХЕ.
Независимо от наличия и объема расширенной (XMS) памяти, компьютер может быть укомплектован платой с дополнительной памятью, не отвечающей каким-либо определенным адресам 16-мегабайтного адресного пространства. Эта память функционирует в соответствии со спецификацией Lotus-Intel-Microsoft Expanded Memory Specification (LIM EMS) и может достигать объема (в версии EMS 4/0) 32 Мбайт. Обращение к EMS-памяти осуществляется через относительно узкие окна (физические страницы) размером по 16 Кбайт, в качестве которых используется часть адресного пространства верхней памяти (от границы 640 Кбайт до 1 Мбайт). Любой блок дополнительной памяти, называемый логической страницей, может быть отображен на физическую страницу в верхней памяти, чем и обеспечивается прямая (хотя и не одновременная) адресация всего пространства дополнительной памяти. В дополнительной памяти, как и в расширенной, обычно размещают электронные диски или кеш- буферы, хотя спецификация EMS 4.0 допускает (в отличие, от EMS 3.2) выполнение программ, находящихся в дополнительной памяти.
Компьютеры типа PC/AT или PS/2 обычно оснащаются расширенной памятью того или иного объема, но не всегда дополнительной. Между тем, некоторые программы в процессе своего выполнения обращаются к дополнительной памяти и при ее отсутствии просто не будут функционировать. Для того, чтобы позволить таким программам выполняться на компьютерах без дополнительной памяти, предусмотрена возможность преобразования части расширенной памяти в дополнительную. Это преобразование осуществляет тот же драйвер ЕММ386.ЕХЕ. По умолчанию для отображения дополнительной памяти используется диапазон адресов верхней памяти DOOO...DFFF, который в этом случае, естественно, выпадает из области блоков верхней памяти UMB. При необходимости область отображения дополнительной памяти можно изменить.
1.3. Регистры процессора
Как уже отмечалось выше, внутренняя архитектура микропроцессоров Intel практически совпадает, если не рассматривать имеющихся в старших моделях процессоров (начиная с МП 80286)' схем организации защищенного режима. Поэтому ниже все эти микропроцессоры будут рассматриваться вместе под общим названием "процессор".
Процессор содержит двенадцать 16-разрядных программно - адресуемых регистров, которые принято объединять в три группы: регистры данных, регистры-указатели и сегментные регистры. Кроме того, в состав процессора входят счетчик команд и регистр флагов (рис. 1.2).
В группу регистров данных включаются регистры АХ, ВХ, СХ и DX. Программист может использовать их по своему усмотрению для временного хранения любых объектов (данных или адресов) и выполнения над ними требуемых операций. При этом регистры допускают независимое обращение к старшим (АН, ВН, СН и DH) и младшим (AL, BL, CL и DL) половинам. Так команда mov BL, AH пересылает старший байт регистра АХ в младший байт регистра ВХ, не затрагивая при этом вторых байтов этих регистров.
Заметьте, что сначала указывается операнд-приемник, а после запятой - операнд-источник. Во многих случаях регистры данных вполне эквивалентны, однако предпочтительнее пользоваться регистром АХ, поскольку многие команды занимают в памяти меньше места и выполняются быстрее, если их операндом является регистр АХ (или его половины AL или АН). С другой стороны, ряд команд использует определенные регистры неявным образом. Так, все команды циклов используют регистр СХ в качестве счетчика числа повторений; в командах умножения и деления регистры АХ и DX выступают в качестве неявных операндов; операции ввода-вывода можно осуществлять только через регистр АХ (или AL) и т.д.
Индексные регистры SI и DI так же, как и регистры данных, могут использоваться произвольным образом. Однако их основное назначение - хранить индексы (смещения) относительно некоторой базы (т.е. начала массива) при выборке операндов из памяти. Адрес базы при этом может находиться в базовых регистрах ВХ или ВР. Специально предусмотренные команды работы со строками используют регистры SI и DI в качестве неявных указателей в обрабатываемых строках.
Регистр ВР служит указателем базы при работе с данными в стековых структурах, но может использоваться и произвольным образом в большинстве арифметических и логических операций.
Последний из группы регистров-указателей, указатель стека SP, стоит особняком от других в том отношении, что используется исключительно как указатель вершины стека, обеспечивая выполнение стековых команд (PUSH, POP и др). Однако это не исключает его использование в качестве операнда в арифметических операциях или операциях пересылки, если требуется изменить положение вершины стека.
Регистры SI, DI, ВР и SP, в отличие от регистров данных, не допускают побайтовую адресацию.
Четыре сегментных регистра CS, DS, ES и SS являются важнейшим элементом архитектуры процессора, обеспечивая адресацию 20-разрядного адресного пространства с помощью 16-разрядных операндов.
АН | AL |
ВН | BL |
СН | CL |
DH | DL |
Регистры-указатели SI DI ВР SP Сегментные регистры CS DS ES SS Прочие регистры IP FLAGS |
Аккумулятор Базовый регистр Счетчик Регистр данных Индекс источника Индекс приемника Указатель базы Указатель стека Регистр программного сегмента Регистр сегмента данных Регистр дополнительного сегмента данных Регистр сегмента стека Указатель команд Регистр флагов |
Рис.1.2. Регистры процессора.
Обращение к памяти (как к стандартной памяти в пределах 640 Кбайт, так и к буферам или ПЗУ в области 640 Кбайт -1 Мбайт) осуществляется исключительно посредством сегментов - логических образований, накладываемых на любые участки физического адресного пространства. Размер сегмента должен находиться в пределах 0 байт - 64 Кбайт (допустимы и иногда используются сегменты нулевой длины). Начальный адрес сегмента, деленный на 16, т.е. без младшей 16-ричной цифры, заносится в один из сегментных регистров. Как правило, это действие выполняет программист с помощью соответствующих программных строк. При обращении к памяти процессор извлекает из сегментного регистра сегментный базовый адрес, умножает его на 16 сдвигом влево на 4 двоичных разряда и складывает с заданным каким-либо образом относительным адресом (смещением), получая 20-разрядный физический адрес адресуемой ячейки памяти (слова или байта). Этот процесс проиллюстрирован на рис. 1.3 на конкретном примере команды inc meml.
Оперативная память слова
Программный сегмент | 06FF | |
Сегмент данных | ||
Ячейка meml | ||
Код команды inc meml
Смещение к ячейке meml
I—— Содержимое DS - 10E2h
10E20h Базовый адрес сегмента (на границе параграфа) lDE22h
lDE24h lDE26h Физический адрес ячейки meml
10Е28П Вычисление физического адреса:
lDE2h * 10h = lDE20h + ООО6h
=1DE26h
Рис. 1.3. Формирование физического адреса
В примере предполагается, что сегмент данных, адресуемый через регистр DS, имеет базовый адрес lDE20h, а ячейка meml расположена в байтах 6 и 7 этого сегмента (смещение meml относительно начала сегмента равно 6).
Поскольку младшая 16-ричная цифра базового адреса сегмента должна быть равна 0, сегмент всегда начинается с адреса, кратного 16, т.е. на границе 16-байтового блока памяти (параграфа). Число, хранящееся в сегментном .регистре, называют сегментным адресом. Следует помнить, что сегментный адрес в 16 раз меньше физического; его можно рассматривать, как номер параграфа, с которого начинается данный сегмент.
Регистр CS обеспечивает адресацию к сегменту, в котором находятся программные коды, регистры DS и ES - к сегментам с данными (таким образом, в любой момент времени программа может иметь доступ к 128 Кбайт данных), а регистр SS -к сегменту стека, который на машинах типа IBM PC, в отличие от других вычислительных систем, может быть очень большим и достигать 64 Кбайт. Сегментные регистры, естественно, не могут выступать в качестве регистров общего назначения.
Указатель команд IP "следит" за ходом выполнения программы, указывая в каждый момент относительный адрес команды, следующей за исполняемой. Регистр IP программно недоступен (IP - это просто его сокращенное название, а не мнемоническое обозначение, используемое в языке программирования); наращивание адреса в нем выполняет микропроцессор, учитывая при этом длину текущей команды. Команды переходов, прерываний, вызова подпрограмм и возврата из них изменяют содержимое IP, осуществляя тем самым переходы в требуемые точки программы.
Регистр флагов, эквивалентный регистру состояния процессора других вычислительных систем, содержит информацию о текущем состоянии процессора (рис. 1.4). Он включает 6 флагов состояния и 3 бита управления состоянием процессора, которые, впрочем, тоже называются флагами.
15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 Разряды
OF | DF | IF | TF | SF | ZF | AF | PF | CF |
Рис. 1.4. Регистр флагов.
Флаг переноса CF (Carry Flag) индицирует перенос или заем при выполнении арифметических операций, а также служит индикатором ошибки при обращении к системным функциям.
Флаг паритета PF (Parity Flag) устанавливается в 1, если результат операции содержит четное число двоичных единиц.
Флаг вспомогательного переноса AF (Auxiliary Flag) используется в операциях над упакованными двоично-десятичными числами. Он индицирует перенос или заем из старшей тетрады (бита 3).
Флаг нуля ZF (Zero Flag) устанавливается в 1, если результат операции равен 0.
Флаг знака SF (Sign Flag) показывает знак результата операции, устанавливаясь в 1 при отрицательном результате.
Управляющий флаг трассировки (ловушки) TF (Trace Flag) используется для осуществления пошагового выполнения программы. Если TF«1, то после выполнения каждой команды процессор реализует процедуру прерывания типа 1 (через вектор, расположенный по адресу 04).
Управляющий флаг разрешения прерываний IF (Interrupt Flag) разрешает (если равен 1) или запрещает (если равен 0) процессору реагировать на прерывания от внешних устройств.
Управляющий флаг направления DF (Direction Flag) используется командами обработки строк. Если DF-0, строка обрабатывается в прямом направлении, от меньших адресов к большим; если DF*1, обработка строки идет в обратном направлении.
Флаг переполнения OF (Overflow Flag) фиксирует переполнение, т.е. выход результата за пределы допустимого диапазона значений.
Для работы с регистром флагов предусмотрен ряд команд. Установка и сброс флагов CF, DF и IF осуществляется командами STC, STD и STI (установка) и CLC, CLD и CLI (сброс). Все содержимое регистра флагов можно сохранить в стеке командой PUSHF и извлечь из стека командой POPF; кроме того, младший байт регистра флагов (флаги CF, PF, AF, ZF и SF) можно переслать в регистр АН командой LAHF или загрузить в регистр флагов из АН командой SAHF.
Сегментация памяти
Перед тем как изучать регистры и команды процессора 8086, необходимо понять, как он адресует память, используя системные сегменты и смещения — термины, часто вызывающие недоразумения.
Используя для представления значения адреса 20 бит, 8086-й процессор может иметь прямой доступ к 1 Мбайт памяти. DOS, ROM BIOS и другие находящиеся в памяти программы уже занимают определенное место памяти персонального компьютера, поэтому остальные программы запускаются, используя меньшее пространство памяти — до 640 Кбайт. Если вы хотите, чтобы ваша программа работала на возможно большем числе компьютеров — ограничьте пределы необходимой памяти.
Замечание
Последние модели процессов, такие как 80386, 80486 и Pentium (известный как 80586), эмулируют режим процессора 8086. Методы, описанные в этой главе, применимы ко всем процессорам 80х86.