верхняя область памяти hma недоступна что делать
Область верхней памяти (HMA)
ЛАБОРАТОРНАЯ РАБОТА №11 РАБОТА С ОЗУ. АДРЕСНОЕ ПРОСТРАНСТВО.
Общие сведения об оперативной памяти
Оперативная память компьютера, иначе называемая оперативным запоминающим устройством (ОЗУ), используется для оперативного обмена информацией (командами и данными) между процессором, внешней памятью (например, дисковой) и различными подсистемами (видеоподсистема, подсистема ввода/вывода, коммуникации и т.д.). ОЗУ представляет собой память с произвольным доступом, поэтому для ее обозначения часто применяется аналогичное английское понятие RAM (Random Access Memory). Произвольность доступа подразумевает возможность операций чтения/записи с любой ячейкой ОЗУ в произвольном порядке. Основными требованиями, предъявляемыми к оперативной памяти являются следующие:
Эффективное использование имеющегося ОЗУ является одной из главных задач, стоящих как перед программистами, так и перед пользователями, стремящимися получить максимальный выигрыш от использования персонального компьютера в своей деятельности. Поэтому для эффективного использования памяти необходимо четкое понимание принципов ее логической организации.
Распределение памяти
С точки зрения использования программами адресного пространства его можно подразделить на следующие участки:
помимо перечисленных категорий следует также особо рассмотреть так называемую область верхней памяти (High Memory Area – HMA), расположенную сразу за пределами 1 Мб, а также области теневой памяти (Shadow Memory). Распределение памяти представлено на рис. 1.
16 Мб
15 Мб
1088 Кб
1024 Кб
640 Кб
0 Кб
Рис 1. Распределение памяти в IBM PC
Стандартная память
По причинам исторического характера программы, являющиеся совместимыми с операционной системой MS-DOS и ее клонами, могут использовать в своей работе только первый мегабайт из всей памяти, установленной на компьютере, если не применяются специальные средства поддержки. Для объяснения этого обстоятельства следует обратить внимание на особенности архитектуры процессора Intel 8086 – базового процессора семейства 80×86. В процессоре 8086 16 ножек (pins) посылают сигналы, соответствующие 16 битам текущих данных, которыми процессор обменивается с системным ОЗУ. Однако данные не имеют никакого смысла сами по себе, если нет возможности следить за тем, что они собой представляют. Системная шина должна знать, куда направляются конкретные данные или откуда они поступили. Для выполнения этой задачи процессор использует еще 20 из своих ножек для создания уникальных адресов памяти. Это дает возможность процессору семейства 8086/8088 адресовать 2 в степени 20 уникальных байтов, что и соответствует 1 мегабайту памяти. В оригинальной архитектуре персонального компьютера 640 Кб из этого 1 Мб было зарезервировано под DOS и прикладные программы, работающие под ее управлением, а область с 640 Кб до 1 Мб была зарезервирована для системного пользования. Большая часть 640 килобайт обычной памяти используется почти постоянно, но в области служебных адресов существуют участки, которые система не использует и которые могут быть доступны для других целей. Участки системной памяти, расположенные между 640 килобайт и 1 мегабайт интенсивно используются программами-расширителями памяти, такими, как Microsoft EMM386, Quarterdeck QEMM и Qualitas 386MAX.
16 (10 в шестнадцатеричной нотации). Это объясняется тем, что адрес, задаваемый в программе, может быть выражен 16-разрядным числом, т.е. содержать не более 4-х шестнадцатеричных цифр. Адресная шина процессора имеет 20 разрядов, поэтому перед вычислением адреса он переводится из 16-разрядной формы в 20-разрядную путем добавления справа еще одной шестнадцатеричной цифры, что эквивалентно умножению на 10 в шестнадцатеричной нотации или на 16 – в десятичной. Выполнив теперь перевод полученного адреса региона А – А0000 в десятичную форму получим число 655360, что доказывает, что регион с номером А находится как раз над границей памяти DOS в 640 Кб.´Рассмотрим это на конкретном примере. Итак, регион А находится в адресном пространстве непосредственно за областью в 640 Кб, то есть, говоря иными словами, адрес его должен превышать 655359 байт (учитывая, что отсчет адресов идет с 0, число 655359 как раз соответствует 640 Кб) в десятичной нотации или 9FFFF в шестнадцатеричной. С учетом вышесказанного, адрес региона с номером А в адресном пространстве будет выглядеть как А000. С точки зрения процессора, этот адрес будет выглядеть как А0000, т.е А000
Выполнив аналогичные вычисления для региона с номером С, получим следующие результаты:
Легко проверить, что если к 640 Кб, которые занимают 10 регионов, идущие перед регионом А, добавить адреса, занимаемые 7 4-килобайтными областями внутри региона А (А0 – А6), то получится:
655359 + 4096 * 7 = 684031
Все приведенные выше сведения, возможно, грешат излишней детальностью, но являются, тем не менее, исключительно важными для понимания дальнейшего изложения.
Расширенная память
Появление расширенной памяти (Extended Memory Specification – XMS) было обусловлено появлением процессора 80286, который имеет на четыре адресных линии больше, чем 8086/8088, что позволяет адресоваться к количеству адресов, большему в 16 раз (2 в степени 4), т.е. к 16 Мб. Адреса памяти выше предела 1MB и называются расширенной памятью. Характерной особенностью процессора Intel 80286 является возможность работы в 2-х режимах: в реальном режиме, в котором 80286 работает как более производительный 8086, и в защищенном, позволяющем адресовать память, лежащую за пределами 1-мегабайтного барьера. Работая в реальном режиме, 80286 не может получить доступа к расширенной памяти и по-прежнему ограничен 1 Мб адресуемого пространства. Чтобы использовать расширенную память, он должен работать в режиме виртуальной (защищенной) адресации. Изначально разработчики этого процессора не предусмотрели простого способа переключаться обратно в режим реальной адресации из режима виртуальной адресации (защиты). Это затруднило использование расширенной памяти в программах и она использовалась в основном под буферы ввода – вывода и печати. Однако, впоследствии, благодаря появлению специальных программ-расширителей – драйверов расширенной памяти – эта проблема была решена. Драйверы расширенной памяти обеспечивают полную поддержку расширенной памяти и позволяют программам осуществлять доступ к ней, а также выполнять программы из расширенной памяти. Наиболее популярными драйверами расширенной памяти являются HIMEM.SYS фирмы Microsoft и DOSHI.SYS фирмы Quarterdeck, входящий в состав пакета QEMM.
На компьютере с микропроцессором 80286, имеющем 24 адресных линии, можно получить до 15MB расширенной памяти (весь объем памяти составляет 16MB). Микропроцессоры 80386 и выше физически способны адресовать 4 гигабайта памяти, имея 32 адресные линии (2 в степени 32 байтов).
Дополнительная память
Дополнительная память (Expanded memory), часто называемая EMS (Expanded Memory Specification) или LIM (согласно ее разработчикам: Lotus, Intel и Microsoft), представляет собой способ доступа к памяти, лежащей за пределами 1 Мб, посредством окна размером 64 Кбайт, лежащего в области служебных адресов между 640 Кб и 1 Мб. При этом используется так называемая схема коммутации банков памяти (bankswitching) – способ управления памятью, когда физическая память разбита на несколько сегментов (банков) длиной, равной размеру адресного пространства процессора. В каждый момент процессор работает с одним банком. Память EMS логически подразделяется на участки размером по 16 Кбайт, называемые страницами. В процессе работы с дополнительной памятью часть содержимого банка размером в 4 страницы, или в 64 Кб отображается в определенный регион, лежащий в пределах 1 Мб, чаще всего в регион E. Данный регион принято называть EMS-фреймом. EMS-фрейм как бы «скользит» по всему адресному пространству банка, что позволяет программам, физически обращаясь к адресам в пределах 1 Мб, получать, тем не менее, доступ ко всей памяти, которая установлена на компьютере.
Дополнительная память особенно полезна потому, что, в отличие от расширенной памяти, она использует только адреса ниже границы в 1MB, следовательно, она может использоваться на машинах с процессорами 8086/8088, кроме того, при программировании нет необходимости использовать адреса, лежащие за пределами 1 Мб. Их отображение в EMS-фрейм будет выполнено драйвером дополнительной памяти. Недостатком EMS-памяти является некоторое замедление при обращении к памяти, которое объясняется накладными расходами, связанными с отображением страниц EMS в EMS-фрейм, переключением банков и т.д. Основными драйверами, обеспечивающими доступ к дополнительной памяти, являются EMM386 (Microsoft), QEMM (Quarterdeck) и 386MAX (Qualitas).
Область верхней памяти (HMA)
Начиная с процессора 80286 можно было наблюдать интересный эффект, связанный с тем, как происходит адресация в пределах 1 Мб. Согласно используемой при программировании в реальном режиме сегментной модели, все адресное пространство может быть представлено в виде пересекающихся между собой участков – сегментов размером в 64 Кб, которые должны начинаться с адреса, кратного 16. До тех пор, пока сегмент начинается с адресов, лежащих до 960 Кб включительно, все более или менее понятно. Однако, как быть в случае, когда сегмент начинается с адреса, лежащего выше 960 Кб? Ведь в этом случае все 64 Кб, входящие в сегмент, просто не уместятся в пределах 1 Мб. В случае с процессором 8086 просто-напросто происходил циклический возврат к началу. Например, если сегмент начинался, скажем, по адресу FB00 или 1028096 байт (1 Мб = 1048576 байт), то первые 4FFF или 20480 байт сегмента располагались в самом верху адресного пространства до 1 Мб включительно, а остальные B000 или 45056 байт – начиная опять с 0 адреса, то есть с самого начала адресного пространства процессора. В
процессоре 80286 ситуация изменилась, поскольку стало возможным адресовать физически более 1 Мб ОЗУ. Таким образом, когда процессор 80286 работает как 8086 и пытается получить доступ к одному из сегментов, лежащих близко к вершине адресного пространства, то адрес, полученный в результате операции будет лежать за пределами 1 Мб и, следовательно, возникает возможность обращаться к 64-килобайтной области (точнее, к 64 Кб минус 16 байт), лежащей за пределами 1 Мб, причем делать это в режиме реальной адресации, без каких-либо средств расширения DOS. Адресуемая подобным образом область размером почти в 64 Кб, лежащая в диапазоне 1024 Кб – 1088 Кб, получила название области верхней памяти (High Memory Area – HMA). В настоящее время типичным применением области HMА стало размещение в ней ядра DOS, что позволяет освободить дополнительно часть памяти ниже 640 Кб для пользовательских программ.
Чтобы ликвидировать разногласия в случаях, когда микропроцессор 80286 работает как микропроцессор 8086, в шину были встроены специальные средства (так называемый мост A20 – A20 Gate), которые заставляют память в режиме реального времени переходить циклически на низшие адреса, как это происходит в 8086/8088. Одним из применений драйвера HIMEM.SYS является отмена действия моста A20, что позволяет программам, написанным особым образом, обращаться к области HMA.
Верхняя память
Память в высших адресах или верхняя память (High Memory) – это область объемом 384 Кбайт, расположенная между границами 640 Кбайт и 1 Mбайт (адреса A000 до FFFF), зарезервированная IBM для системного аппаратного обеспечения – для видеопамяти, BIOS и прочего. Во многих случаях она, однако, используется не полностью, и в ней образуются «дыры» – свободные участки, которые не используются в служебных целях, но к которым не имеют прямого доступа программы, работающие в 640 Кб основной памяти. Посредством расширителей памяти – таких как EMM386 (производства Microsoft), QEMM (производства Quarterdeck) и 386MAX (производства Qualitas) можно управлять этой областью зарезервированной памяти и перенести туда резидентные программы из основной памяти, тем самым освобождая больше обычной памяти под прикладные программы.
Структура верхней памяти
Рис 2. Особенности адресации в процессорах Intel 8086 (a) и Intel 80286 и старших (б)
Для эффективного использования памяти, расположенной в верхних адресах, необходимо, прежде всего, знать, какие именно регионы этой памяти, используются всегда, а какие – зачастую остаются свободными.
Как уже упоминалось, верхняя память представлена 384 Кб, расположенными в адресном пространстве между 640 Кб и 1 Мб и включает в себя рассмотренные ранее регионы А, B, C, D, E и F. Следует сразу же заметить, что не существует четких стандартов на использование всех этих регионов. В общем случае использование участков верхней памяти определяется конкретной конфигурацией и может быть разным на разных машинах. В то же время существуют определенные рассматриваемые ниже соглашения об их распределении.
Другой стандартной областью является область F. В ней располагаются процедуры и данные BIOS и некоторая другая важная системная информация. Тем не менее, не все системы полностью занимают весь отведенный участок размером 64 Кб, и не все из этих 64 Кб нужны после загрузки. Например, в некоторых системах память от F000 до F800 используется программой установки и диагностики, которая может быть вызвана во время загрузки. Поскольку этот участок не используется после загрузки, можно позволить программе управления памятью разместить там что-нибудь другое.
Области C и D запутаны больше всего. В системах, имеющих EGA- и VGA-адаптеры, видео-ПЗУ обычно находится на дне области C. Остаток региона С, не используемый для размещения видеоПЗУ (адреса выше C800), а также вся область D применяются для размещения драйверов и прочего программного обеспечения, обеспечивающего поддержку всевозможного специфического оборудования – сетевых карт, адаптеров SCSI и т.д.
Наконец, регион E в случае наличия в системе диспетчера дополнительной (EMS) памяти используется как EMS-фрейм.
Подытоживая все эти сведения, можно заметить, что в среднестатистической системе гарантированно занятыми являются только регионы А (видеопамять графического режима для адаптеров EGA, VGA и выше) и F (системная BIOS), кроме того, почти всегда (при наличии цветного адаптера) занята область размером 16 Кб, лежащая в адресах B800 – BC00 (видеопамять текстового режима), и область размером в 32 Кб в начале региона С в адресах C000 – C800 (видеоПЗУ). Занятость же прочих регионов верхней памяти в общем случае не определена. Таким образом, стандартно занято 64 Кб + 64 Кб + 16 Кб + 32 Кб = 176 Кб верхней памяти. Прочие 208 Кб, вообще говоря, могут быть свободны и использованы для хранения программ, которые обычно располагаются в основной памяти. Реально, во многих случаях занятым оказывается еще и регион E, содержащий EMS-фрейм, а вторая половина региона C и регион D, напротив, чаще всего свободны. В силу данного обстоятельства в верхней памяти обычно остаются неиспользованными как минимум 96 Кб.
Разумеется, хранение в верхней памяти прикладных программ, работающих в адресном пространстве 640 Кб, было бы сопряжено со слишком большими трудностями, однако, если речь идет о драйверах, которые не должны постоянно выгружаться и загружаться в память, а должны находиться в ней резидентно, то использование верхней памяти в данном случае имеет большие преимущества. Поэтому была изобретена технология, позволяющая переносить драйверы, расположенные в обычной памяти, в свободные блоки верхней памяти, освобождая таким образом основное ОЗУ. Блоки верхней памяти, используемые подобным образом, получили название Upper Memory Blocks – UMB. Организацией блоков UMB и переносом в них драйверов из нижней памяти занимаются все те же менеджеры памяти, о которых уже шла речь выше – QEMM, EMM386, 386MAX и т.д.
В качестве примера, иллюстрирующего преимущество правильного использования верхней памяти и знания структуры памяти вообще, можно привести следующий факт. Если после загрузки DOS и необходимых драйверов устройств остаются свободными примерно 550-570 Кб ОЗУ, то при помещении ядра DOS в HMA с помощью драйвера HIMEM.SYS (или DOSHI.SYS), а также драйверов устройств в UMB посредством EMM386 или QEMM доступными для прикладных программ оказываются уже 620-635 Кб (а иногда – и больше ). Таким образом, правильное конфигурирование системы и настройка менеджеров памяти позволяет буквально из ничего выжать дополнительные 50-85 Кб (удавалось получать даже 100 Кб)!
Рис 3. Структура блоков верхней памяти (UMB)
Теневая память
Теневая память (Shadow Memory) ускоряет обращение к обычно медленной постоянной памяти, такой как System BIOS или VideoROM BIOS за счет ее подмены быстрой оперативной памятью, имеющей более высокую разрядность. Теневая память подразделяется на теневую RAM (Shadow RAM) и теневую ROM (Shadow ROM). При инициализации Shadow ROM содержимое затеняемой области копируется в область теневой памяти и при дальнейшем обращении к затеняемым участкам памяти вместо реального ROM подставляется участок Shadow RAM, запись же в эту область и вовсе блокируется. Shadow ROM отличается тем, что при записи в ROM запись происходит как собственно в ROM, так и в участок затемняющей его теневой памяти. Области, используемые для затемнения постоянной памяти находятся в верхней памяти. Как правило Shadow Memory располагается в регионах C и D и представляет собой, чаще всего, копию содержимого ПЗУ различных адаптеров для убыстрения доступа к ним. Обычно включение или выключение теневой памяти осуществляется через BIOS Setup компьютера. Эту же функцию имеют и некоторые менеджеры памяти, в частности EMM386.
10. РАСШИРЕННАЯ ПАМЯТЬ
Однако в составе MS-DOS версии 4.0 и более поздних версий появился драйвер расширенной памяти HIMEM.SYS, который в некоторой степени облегчает жизнь программистам, составляющим программы для MS-DOS. Этот драйвер расширяет основное адресное пространство 640K еще примерно на 64 килобайта и предоставляет относительно удобное средство для хранения в расширенной памяти массивов данных.
Будучи установлен в операционной системе, драйвер HIMEM.SYS предоставляет программам интерфейс в соответствии со спецификацией XMS (eXtended Memory Specification), разработанный корпорациями LOTUS, INTEL, MICROSOFT, AST Research.
На рисунке схематично показано расположение различных перечисленных выше блоков памяти в адресном пространстве:
Для установки драйвера файл CONFIG.SYS должен содержать строку:
Параметр /HMAMIN= (необязательный) задает минимальный размер памяти, который могут использовать программы в области HMA. Размер задается в килобайтах. Смысл использования этого параметра заключается в том, чтобы позволять использовать область HMA только тем программам, которые затребуют из этой области не меньше h килобайт. Это нужно для того, чтобы более эффективно использовать область HMA.
Если параметр не задан, используется по умолчанию значение 0. Это означает, что первая же программа, запросившая область HMA, получит к ней доступ. Программа, запущенная следом и, возможно, использующая эту память эффективнее, уже не сможет воспользоваться областью HMA.
Спецификация XMS содержит описание программного интерфейса драйвера HIMEM.SYS и рекомендации по использованию области памяти HMA.
10.3.1. Проверка подключения драйвера
Приведем фрагмент программы, проверяющей подключение драйвера:
10.3.2. Получение адреса управляющей программы
Для вызова драйвера программа должна получить адрес специальной управляющей программы, которая выполняет все функции по обслуживанию расширенной памяти и области HMA.
В дальнейшем полученный адрес используется для выполнения функций по обслуживанию расширенной памяти. Перед вызовом управляющей программы код требуемой функции должен быть загружен в регистр AH:
Программы, которые обращаются к управляющей функции, должны перед вызовом функции иметь размер стека не менее 256 байтов.
10.3.3. Описание функций драйвера HIMEM.SYS
Приведем подробное описание этих функций в соответствии со спецификацией XMS версии 2.0.
Получить версию XMS
Функция возвращает номера версии и модификации XMS в двоично-десятичном (BCD) формате. Например, если AX=0250h, это означает, что драйвер реализует спецификацию XMS версии 2.50. Дополнительно функция позволяет проверить наличие в системе области HMA.
Запросить область HMA
С помощью этой функции программа может зарезервировать для себя область HMA. Задаваемый в регистре DX размер памяти сравнивается с указанным в параметре драйвера /HMAMIN=. Область HMA распределяется запросившей программе только в том случае, если запрошенный в регистре DX размер больше или равен указанному в параметре /HMAMIN. Такой механизм позволяет ограничить использование области HMA только теми программами, которые используют ее наилучшим образом.
Поясним это на примере. Пусть при инициализации операционной системы из файла AUTOEXEC.BAT запускаются две программы. Одна из них использует 10 килобайт из области HMA и запускается первой (в регистре DX функции 01h эта программа указывает значение 10240). Вторая запускаемая программа использует 40 килобайтов и запускается после первой. Очевидно, что вторая программа использует область HMA более эффективно. Но так как область HMA уже распределена первой программе, вторая программа не сможет ее использовать.
Задавая параметр /HMAMIN=40, мы запретим распределение области HMA тем программам, которые используют в ней меньше 40 килобайтов. Теперь первая программа не получит доступ к области HMA, даже если она будет запускаться до второй, использующей 40 килобайтов памяти из области HMA.
Освободить область HMA
Программы, которые запрашивали область HMA, должны освободить ее с использованием этой функции. При этом данные, которые находились в этой области, будут потеряны.
После того, как программа освободила область HMA, эта область становится доступной другим программам.
Глобальное открывание линии A20
Эта функция предназначена для тех программ, которые будут использовать область HMA. Она разрешает работу заблокированной по умолчанию 21-ой адресной линии процессора. Перед возвратом управления системе программа должна закрыть линию A20 с помощью функции 04h.
Глобальное закрывание линии A20
Функция предназначена для тех программ, которые используют область HMA. Она должна выполняться перед завершением работы такой программы.
Локальное открывание линии A20
Эта функция предназначена только для тех программ, которые непосредственно управляют расширенной памятью. Перед завершением работы программа должна закрыть линию A20 при помощи функции 06h.
Локальное закрывание линии A20
Функция отменяет разрешение линии A20, запрошенное предыдущей функцией. Она предназначена только для тех программ, которые непосредственно управляют расширенной памятью.
Определение состояния линии A20
Функция выполняет попытку адресоваться за границу 1 мегабайта памяти и проверяет, не происходит ли при этом обращение в начало памяти (т.е. «свертка памяти»).
Определение размера свободной расширенной памяти
При определении размера свободной расширенной памяти в возвращаемое значение не включается 64К области HMA, даже если эта область не используется программами.
Получить блок EMB
Функция заказывает блок EMB из пула свободной расширенной памяти. При успешном выполнении запроса функция возвращает индекс полученного блока, который должен использоваться программой для выполнения всех операций с блоком EMB. Если блок EMB программе больше не нужен, она должна освободить его с помощью функции 0Ah.
Освободить блок EMB
Функция освобождает блок EMB, заказанный предыдущей функцией. При этом все данные, находившиеся в блоке, будут потеряны.
Копирование блоков EMB
Поле Length управляющей структуры указывает количество пересылаемых байтов. Это количество должно быть четным.
Поля SourceHandle и DestHandle указывают, соответственно, индексы исходного и результирующего блоков EMB. Если в качестве индекса задано значение 0000h, это означает, что в качестве источника или приемника данных используется обычная память.
Поля SourceOffset и DestOffset указывают 32-битовое смещение в блоке EMB или адрес в обычной памяти. В последнем случае этот адрес имеет стандартный формат сегмент:смещение.
Функция копирования сама управляет линией A20, восстанавливая ее состояние после выполнения копирования. Поэтому программе не требуется управлять линией A20.
Во время выполнения копирования разрешены прерывания.
Блокирование EMB
Функция блокирует EMB и возвращает его базовый адрес как линейный 32-разрядный адрес. Для заблокированного EMB невозможно выполнить операцию копирования. Полученный линейный адрес действителен только для заблокированного EMB.
Разблокирование EMB
Функция разблокирует EMB, заблокированный при вызове предыдущей функции. Полученный от нее линейный адрес становится недействительным.
Получить информацию об индексе EMB
Эта функция используется для получения различной информации об используемых блоках EMB. Линейный адрес блока может быть получен с помощью фунции 0Ch.
Изменить размер EMB
Функция изменяет размер незаблокированного EMB. Если блок уменьшается в размерах, данные в старших адресах блока будут потеряны.
Запросить область UMB
Эта функция позволяет программе получить дступ к блокам UMB, лежащих в пределах первого мегабайта адресного пространства. Для использования этих блоков не требуется управлять линией A20.
Если вам надо определить размер доступной области UMB, задайте при вызове этой функции DX=FFFFh.
Освободить область UMB
После освобождения блока EMB данные, которые там находились, будут потеряны.
10.3.4. Коды ошибок
Приведем таблицу кодов ошибок, возвращаемых функциями в регистре BL:
Код | Ошибка |
00h | Нет ошибки, нормальное завершение |
80h | Функция не реализована в текущей версии драйвера |
81h | Обнаружен драйвер VDISK.SYS, с этим драйвером драйвер HIMEM.SYS несовместим |
82h | Ошибка при работе с линией A20 |
8Eh | Общая ошибка драйвера |
8Fh | Катастрофическая ошибка драйвера |
90h | Область HMA не существует |
91h | Область HMA уже используется |
92h | Содержимое регитра DX меньше парметра /HMAMIN= |
93h | Область HMA не распределена программе |
94h | Линия A20 все еще разблокирована |
A0h | Вся расширенная память уже распределена |
A1h | Больше нет свободных индексов EMB |
A2h | Неправильный индекс EMB |
A3h | Неправильный SourceHandle |
A4h | Неправильный SourceOffset |
A5h | Неправильный DestHandle |
A6h | Неправильный DestOffset |
A7h | Неправильный Length |
A8h | Неразрешенное перекрытие данных при выполнении операции пересылки данных |
A9h | Произошла ошибка четности |
AAh | EMB не заблокирован |
ABh | EMB заблокирован |
ACh | Переполнение счетчика блокировок EMB |
ADh | Не удалось выполнить блокировку EMB |
B0h | Доступен UMB меньшего размера |
B1h | Нет доступных блоков UMB |
B2h | Задан неправильный сегмент UMB |
Первая программа демонстрирует проверку подключения драйвера и использование его основных функций:
Теперь приведем пример программы, использующей область HMA для выполнения процедуры генерации звукового сигнала. Программа получает доступ к области HMA, копирует в нее процедуру генерации звукового сигнала и вызывает эту процедуру с помощью межсегментной команды call:
В программе использована макрокоманда BEEP, описанная в файле sysp.inc:
Следующая программа демонстрирует использование функции копирования. Сообщение копируется из области основной памяти в область расширенной памяти, а затем обратно в область основной памяти, но в другое место:
Приведем текст программы, позволяющей программам, составленным на языке программирования Си, использовать функции драйвера расширенной памяти. Эта программа будет работать только в моделях памяти Small и Compact. Для других моделей памяти требуется изменить строки программы, в которых передаваемые функциям параметры извлекаются из стека и тип процедур (FAR):
Приведем пример программы, демонстрирующей использование некоторых функций XMM: