Иллюстрированный самоучитель по SVGA

Использование функций драйвера

Для корректной работы с расширенной памятью задачи должны выполнять определенную последовательность действий, а именно:

  1. Проверить наличие менеджера, поддерживающего функции EMS.
  2. Получить код сегмента, на который отображается расширенная память.
  3. Определить наличие требуемого пространства расширенной памяти.
  4. Отобразить часть пространства ОЗУ на физические страницы.
  5. В пределах сегмента работать с расширенной памятью как с обычной.
  6. При достижении границ сегмента повторять пункты 4 и 5.
  7. Перед завершением задачи вернуть память менеджеру.

Выполнение первого пункта списка является скорее данью традиции, чем необходимостью, поскольку ПК на базе Intel 386 и всех последующих моделей обязательно имеют оборудование для доступа к расширенной памяти. Для проверки можно, например, с помощью функции 40h определить статус, а с помощью функции 4бп – номер версии драйвера и убедиться, что он не меньше чем 4.0. Остальные пункты списка обязательно должны выполняться, причем в той последовательности, в которой они перечислены.

Специальные переменные

При работе с Expanded memory обязательно используются код сегмента расширенной памяти и идентификаторы выделенных блоков. В некоторых случаях могут быть нужны номера последних логических страниц в выделенных блоках и другие величины. Для их хранения в разделе данных задачи надо выделить специальные переменные, количество которых зависит от количества открытых блоков.

Если задача запрашивает у драйвера только один блок большого размера, то для работы с ним нужны следующие переменные:

EBuff dw 0; код сегмента для доступа к расширенной памяти
Ehndlr dw 0; идентификатор блока выделенного для задачи
Curpg db 0; номер текущей логической страницы блока
Lastpg db 0; номер последней логической страницы блока

Номера текущей и последней страниц нужны при работе с большими блоками, размер которых превышает 65 536 байтов (4 страницы). При работе с ними приходится многократно отображать его логические страницы на физические. Если же размер блока не превышает стандартного сегмента ОЗУ, то он отображается на физические страницы только один раз и при дальнейшей работе номера страниц не нужны.

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

Резервирование блока

Предположим, что для выполнения задачи требуется непрерывное пространство расширенной памяти (блок) размером в 1 Мбайт. Для резервирования такого блока задача должна запросить у драйвера исполнение функции 43h, указав в регистре bx 64 страницы (размер страницы составляет 16 Кбайт). Если это первый запрос, обращенный к драйверу, то предварительно надо выполнить функцию 4 in для определения состояния драйвера и получения кода сегмента для доступа к памяти.

Фрагмент программы, выполняющий резервирование блока размером в 1 Мбайт, приведен в примере Б.5. Его надо включить в ту часть задачи, где выполняются подготовительные действия. Например, сразу после команд, приведенных в примерах Б.3 или Б.4.

Пример Б.5. Создание в расширенной памяти блока размером 1 Мбайт.

mov ax, 4100h код функции запроса сегмента
int 67h обращение к драйверу
or ah, ah функция выполнена?
je @F › да
jmp emmerr › ошибка при исполнении функции
@@: mov EBuff, bx сохраняем код сегмента
mov bx, 64 размер запрашиваемого блока
mov ax, 4300h код функции выделения памяти
int 67h обращение к драйверу
or ah, ah блок выделен?
je @F › да
jmp emmerr › ошибка при выделении блока
@@: mov Ehndlr, dx сохраняем идентификатор блока
mov Curpg, 0 номер текущей страницы блока
mov Lastpg, 63 номер последней страницы блока
; Продолжение текста программы

Выполнение примера Б.5 начинается с запроса кода сегмента для доступа к расширенной памяти. Если при возврате из драйвера регистр ah очищен, то запрос исполнен успешно, в противном случае произойдет переход на метку emmerr. для вывода аварийного сообщения.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.