Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

Защищенный режим процессоров Intel 80286/80386/80486

© Александр Фролов, Григорий Фролов
Том 4, М.: Диалог-МИФИ, 1993, 234 стр.

[Назад] [Содеожание] [Дальше]

6.4. Интерфейс DPMI

Для создания программ, работающих в защищённом режиме, фирмы Microsoft, Intel, IBM, Lotus, Phar Lap, Rational Systems, Borland, Quarterdeck разработали интерфейс с защищённым режимом - DPMI (DOS Protected Mode Interface). Пользуясь этим интерфейсом, программы, стартующие как обычные DOS-программы реального режима, могут переключиться в защищённый режим и работать с расширенной или даже виртуальной памятью. Интерфейс DPMI обеспечивается специальной программой, называемой сервером DPMI. Сервером может быть отдельная резидентная программа, либо средства для поддержки DPMI могут входить в состав операционной системы (например, WINDOWS и OS/2 версии 2.0 позволяют работающим под их управлением DOS-программам использовать интерфейс DPMI).

В этом разделе мы кратко опишем функции DPMI, а в разделе, посвященном виртуальной машине WINDOWS, приведём пример программы, работающей в защищённом режиме с использованием функций DPMI спецификации 0.9. Спецификация DPMI версии 0.9 поддерживается операционной системой WINDOWS версий 3.0 и 3.1, работающей в расширенном режиме на процессорах i80386 или i80486.

Все функции DPMI реализованы в рамках прерывания INT 31h, обработчиком этого прерывания является сервер DPMI. Прежде чем использовать функции DPMI, программа с помощью описанных ниже функций прерываний INT 2Fh должна убедиться в присутствии поддержки DPMI, получить адрес процедуры переключения в защищённый режим и выполнить это переключение.

Программа должна вызывать прерывание INT 31h после переключения в защищённый режим, в реальном режиме это прерывание вызывать нельзя.

Получить адрес перехода в защищённый режим

С помощью этой функции программа может определить наличие в системе интерфейса DPMI и получить адрес процедуры перехода в защищённый режим работы.

Для вызова этой функции необходимо использовать прерывание INT 2Fh, загрузив регистр AX следующим образом:

Регистры на входе:
AX      1687h




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

Регистры на выходе:
AX      00h
BX      Если установлен бит 0, данная реализация DPMI поддерживает 
работу с 32-разрядными программами.
CL      Тип процессора:
     02h = 80286
     03h = 80386
     04h = 80486
DH      Верхний (major) номер версии используемой спецификации DPMI.
DL      Нижний (minor) номер версии используемой спецификации DPMI.
SI      Количество параграфов памяти, требуемых для личной области 
данных сервера DPMI. Программа должна заказать эту память 
у операционной системы перед переходом в защищённый режим.
ES:DI   Адрес процедуры, которую необходимо вызвать для входа 
в защищённый режим.




Если выполнение функции закончилось с ошибкой, содержимое регистра AX не равно нулю.

Вход в защищённый режим

После того, как программа получила адрес процедуры для входа в защищённый режим, она может вызвать эту процедуру при помощи команды CALL. Перед вызовом необходимо загрузить регистры:

Регистры на входе:
AX      Разрядность программы. Если программа является 32-разрядной, 
в регистре AX необходимо установить бит 0 в единицу.
ES      В этот регистр необходимо загрузить сегментный адрес буфера, 
который будет использован сервером DPMI. Размер буфера должен быть 
определён при помощи предыдущей функции (регистр SI).




После загрузки регистров необходимо выполнить вызов процедуры с адресом, который был получен в регистрах ES:DI после вызова предыдущей функции.

Если функция выполнилась успешно, флаг CARRY сброшен и программа выполняется в защищённом режиме.

Регистры на выходе
CS      Селектор, которому соответствует базовый адрес сегмента 
кода программы и предел 64 килобайта.
SS      Селектор для сегмента стека, базовый адрес соответствует 
стеку реального режима, предел - 64 килобайта.
DS      Селектор, соответствующий сегменту данных реального режима, 
предел - 64 килобайта.
ES      Селектор, указывающий на PSP программы с пределом 100h байт.
FS, GS  0 (если программа работает на процессоре i80386 или i80486).
ESP     Если программа работает в 32-разрядном режиме, старшее 
слово регистра ESP будет равно 0.




Остальные регистры не изменяются.

Если функция выполнилась с ошибкой, флаг CARRY устанавливается в единицу и программа продолжает выполнение в реальном режиме.

После входа в защищённый режим вам становится доступен интерфейс DPMI через функции прерывания INT 31h.

Для завершения своей работы программа, использующая DPMI, должна выдать прерывание INT 21h (функция 4Ch) - это обычный способ завершения программ, работающих в среде MS-DOS.

Приведём фрагмент программы, использующей DPMI. На примере этого фрагмента мы покажем, как убедиться в том, что в системе имеется интерфейс DPMI, как войти в защищённый режим и завершить работу программы.

; Получаем адрес точки входа в защищённый режим

        mov     ax, 1687h
        int     2Fh
        test    ax, ax
        jnz     Cant_Enter_PMode ; не можем войти в защищённый режим

        mov     [PMode_Entry_Seg], es
        mov     [PMode_Entry_Off], di

; Заказываем память для сервера DPMI (если это требуется)

        test    si, si
        jz      Enter_PMode_Now
        mov     bx, si
        mov     ah, 48h
        int     21h
        jc      Cant_Enter_PMode
        mov     es, ax

; Устанавливаем защищённый режим

Enter_PMode_Now:
        xor     ax, ax
        call    DWORD PTR [PMode_Entry_Off]
        jc      Cant_Enter_PMode

; Программа работает в защиённом режиме.

;      Здесь располагаются строки
;      вашей программы.

; Завершение программы и возврат в DOS

        mov     ax, 4C00h
        int     21h




Определение текущего режима работы

Если ваша программа может работать и в реальном режиме и в защищённом, с помощью этой функции вы можете определить текущий режим работы.

Для выполнения функции необходимо вызвать прерывание INT 2Fh, предварительно загрузив регистр AX:

Регистры на входе:
AX      1686h
Регистры на выходе:
AX      0, если программа работает в защищённом режиме под управлением DPMI,
не равно 0, если программа работает в реальном или виртуальном режиме.




Создать дескриптор в таблице LDT

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

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

Регистры на входе:
AX      0000h
CX      Количество создаваемых дескрипторов.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.
AX      Базовый селектор.




Если программа заказывала несколько селекторов, AX содержит первый селектор из созданного массива. Для получения остальных селекторов необходимо воспользоваться функцией 00003h.

Освободить дескриптор в таблице LDT

Функция используется для освобождения дескрипторов, созданных в LDT предыдущей функцией.

Регистры на входе
AX      0001h
BX      Селектор освобождаемого дескриптора.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.




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

Преобразование сегмента в дескриптор

Функция используется для преобразования сегментной компоненты адреса реального режима в дескриптор.

Регистры на входе
AX      0002h
BX      Сегментный адрес реального режима.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.
AX      Селектор, соответствующий дескриптору, созданному 
для адресации сегмента реального режима.




Дескриптор, созданный данной функцией, не может быть освобождён, поэтому эту функцию имеет смысл использовать для адресации таких областей памяти, которые будут нужны на всём протяжении работы программы (область данных BIOS, память видеоконтроллера и т.д.).

Получить значение инкремента для вычисления следующего селектора в массиве

Если вы создали несколько дескрипторов в LDT при помощи функции 0000h, то этой функцией будет возвращён только первый селектор, соответствующий первому дескриптору в созданном массиве. Для вычисления остальных селекторов ваша программа должна использовать функцию 0003h. Эта функция возвращает значение, которое вы будете прибавлять к базовому селектору для вычисления остальных селекторов в массиве.

Регистры на входе
AX      0003h
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.
AX      Значение для инкремента базового селектора.




Зарезервированные функции

Функции 0004h и 0005h в спецификации DPMI версии 0.9 зарезервированы и не должны вызываться из вашей программы.

Получить базовый адрес сегмента

С помощью этой функции ваша программа может определить 32-разрядный базовый адрес сегмента по его селектору.

Регистры на входе
AX      0006h
BX      Селектор сегмента, для которого требуется получить базовый адрес.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.
CX:DX   32-разрядный базовый адрес сегмента.




Установить базовый адрес сегмента

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

Регистры на входе
AX      0007h
BX      Селектор сегмента, для которого требуется установить базовый адрес.
CX:DX   Устанавливаемый 32-разрядный линейный базовый адрес сегмента.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.




Установить предел сегмента

Эта функция устанавливает предел сегмента в дескрипторе, соответствующем заданному селектору.

Регистры на входе
AX      0008h
BX      Селектор сегмента, для которого требуется установить 
новое значение предела.
CX:DX   Устанавливаемое 32-разрядное значение предела сегмента.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.




Установить поле прав доступа в дескрипторе

При помощи этой функции вы можете модифицироать поле прав доступа в дескрипторе, созданного вашей программой.

Регистры на входе
AX      0009h
BX      Селектор сегмента, для которого требуется установить 
новые права доступа.
CL      Байт прав доступа.
CH      Расширение байта прав доступа для процессора 
i80386/i80486, используется только 32-разрядными реализациями DPMI.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.




В расширении байта прав доступа старший бит (бит 7) - бит гранулярности, который определяет интерпретацию поля предела (0 - предел в байтах, 1 - предел в страницах). Бит 6 указывает режим работы процессора (0 - 16-разрядный, 1 - 32-разрядный). Бит 5 и 2-3 должны быть равны 0. Бит 4 может содержать любое значение.

Создание алиасного дескриптора для сегмента кода

Так как в защищённом режиме модификация сегмента кода с использованием селектора CS невозможна, для решения такой задачи необходимо создать дескриптор сегмента данных, который бы указывал на сегмент кода (т.е. имел бы такой же базовый адрес и предел). Такой дескриптор является алиасом дескриптору сегмента кода и может быть создан при помощи функции 000Ah.

Если алиас больше не нужен, он может быть уничтожен при помощи функции 0001h.

Регистры на входе
AX      000Ah
BX      Селектор сегмента кода, для которого требуется создать алиас.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.




Получить дескриптор

С помощью этой функции программа может скопировать в буфер размером 8 байт дескриптор, соответствующий заданному селектору.

Регистры на входе
AX      000Bh
BX      Селектор сегмента, для которого требуется получить дескриптор.
ES:(E)DI        Указатель на буфер размером 8 байт, в который будет 
скопирован дескриптор. Для 32-разрядных программ необходимо 
использовать регистр EDI.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.




Установить дескриптор

Функция выполняет действия, обратные предыдущей - копирует содержимое 8-байтового буфера в дескриптор, заданный селектором.

Регистры на входе
AX      000Ch
BX      Селектор сегмента, для которого требуется установить дескриптор.
ES:(E)DI        Указатель на буфер размером 8 байт, из которого будет 
взята информация для установки дескриптора. Для 32-разрядных программ 
необходимо использовать регистр EDI.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.




Программа может модифицировать только дескрипторы из своей локальной таблицы LDT, созданные там с помощью функции 0000h.

Получить конкретный дескриптор в таблице LDT

Функция позволяет получить дескриптор по его селектору.

Регистры на входе
AX      000Dh
BX      Селектор сегмента, для которого требуется получить дескриптор.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.




Для этой функции сервер DPMI резервирует первые 16 дескрипторов в таблице LDT. Программа может освободить полученные с помощью этой функции дескрипторв при помощи функции 0001h.

Получить блок памяти из пула свободной памяти DOS

С помощью этой функции программа может получить от DOS блок памяти, лежащий в пределах первого мегабайта адресного пространства. Для полученного блока памяти функция создаёт один или несколько дескрипторов (в зависимости от размера блока) и возвращает как сегмент блока для реального режима, так и базовый селектор для доступа к блоку в защищённом режиме.

Если размер запрошенного блока превышает 64 килобайта, функция создаст массив дескрипторов и возвратит базовый селектор. Для получения остальных селекторов вы сможете использовать значение инкремента, полученное после вызова функции 0003h.

Дескрипторы, созданные этой функцией, можно освобождать только с помощью функции 0101h.

Регистры на входе
AX      0100h
BX      Размер блока в параграфах (напомним, что размер 
параграфа составляет 16 байт).

Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.
В случае ошибки регистр AX содержит код ошибки, полученный от DOS:
        07h - разрушен блок MCB;
        08h - слишком большой размер заказанного блока.
В последнем случае регистр BX содержит максимально возможный 
размер блока в параграфах.
AX      Сегмент реального режима полученного блока.
DX      Селектор для доступа к полученному блоку в защищённом режиме.




Освободить блок памяти, взятый из пула DOS

Функция предназначена для освобождения памяти, полученной при помощи предыдущей функции.

Регистры на входе
AX      0101h
DX      Селектор освобождаемого блока.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.
В случае ошибки регистр AX содержит код ошибки, полученный от DOS:
        07h - разрушен блок MCB;
        09h - неправильное задание сегментного адреса 
		освобождаемого блока памяти.




Изменить размер блока памяти, полученного из пула DOS

С помощью этой функции программа может увеличить или уменьшить размер блока памяти, полученного функцией 0100h.

Регистры на входе
AX      0102h
BX      Новый размер блока памяти в параграфах.
DX      Селектор модифицируемого блока.

Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.
В случае ошибки регистр AX содержит код ошибки, полученный от DOS:
        07h - разрушен блок MCB;
        08h - слишком большой размер заказанного блока.
В этом случае регистр BX содержит максимально возможный размер блока в параграфах.
        09h - неправильное задание сегментного адреса модифицируемого блока памяти.




Получить вектор прерывания реального режима

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

Регистры на входе
AX      0200h
BL      Номер прерывания.
Регистры на выходе:
CARRY   0
CX:DX   Адрес обработчика прерывания в формате <сегмент:смещение>.




Установить вектор прерывания реального режима

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

Регистры на входе
AX      0201h
BL      Номер прерывания.
CX:DX   Адрес обработчика прерывания в формате <сегмент:смещение>.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.




Получить адрес обработчика исключения с заданным номером

Функция возвращает адрес текущего обработчика исключения с заданным номером в формате защищённого режима.

Регистры на входе
AX      0202h
BL      Номер исключения (00h - 1Fh).
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.
CX:(E)DX        Адрес обработчика исключения в формате <селектор:смещение>.




Установить адрес обработчика исключения с заданным номером

Функция может быть использована для установки собственного обработчика исключений.

Регистры на входе
AX      0203h
BL      Номер исключения (00h - 1Fh).
CX:(E)DX        Адрес обработчика исключения в формате <селектор:смещение>.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.




Получить вектор прерывания защищённого режима

Функция возвращает адрес обработчика заданного прерывания в формате защищённого режима.

Регистры на входе
AX      0204h
BL      Номер прерывания.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.
CX:(E)DX        Адрес обработчика прерывания в формате <селектор:смещение>.




Установить вектор прерывания защищённого режима

С помощью этой функции программа может установить собственный обработчик защищённого режима для любого прерывания.

Регистры на входе
AX      0205h
BL      Номер прерывания.
CX:(E)DX        Адрес обработчика прерывания в формате <селектор:смещение>.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.




Эмуляция прерывания реального режима

Эта функция предназначена для эмуляции выполнения прерывания в реальном режиме. С её помощью вы сможете находясь в защищённом режиме обращаться к функциям BIOS, DOS и к другим прерываниям реального режима.

Регистры на входе
AX      0300h
BL      Номер прерывания.
BH      Байт флагов. Если установлен в единицу бит 0, выполняется 
сброс контроллера и линии A20. Остальные биты зарезервированы и 
должны быть сброшены в нуль.
CX      Количество слов, которые должны быть скопированы из стека 
защищённого режима в стек реального режима.
ES:(E)DI        Адрес управляющей структуры для вызова прерывания.

Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.
ES:(E)DI        Адрес модифицированной (в результате выполнения 
обработчика прерывания) управляющей структуры в формате защищённого режима.




Управляющая структура содержит значения для инициализации регистров перед вызовом эмулируемого прерывания реального режима. Она имеет следующий формат:

Таблица 11. Формат управляющей структуры для эмуляции прерывания реального режима средствами DPMI.

Смещение Регистр
00h EDI
04h ESI
08h EBP
0Ch Зарезервировано
10h EBX
14h EDX
18h ECX
1Ch EAX
20h FLAGS
22h ES
24h DS
26h FS
28h GS
2Ah IP
2Ch CS
2Eh SP
30h SS

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

     push    Parametr1
     push    Parametr2
     push    Parametr3

     mov     cx, 3           ; Копируем три параметра
     mov     ax, 0301h
     int     31h
     add     sp, 6           ; Восстанавливаем стек




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

Parametr1
Parametr2
Parametr3
CS для возврата
IP для возврата




Указатель стека реального режима SS:SP установлен на слово, содержащее IP для возврата.

Вызов процедуры реального режима, заканчивающейся командой RET FAR

Эта процедура позволяет выполнить вызов процедуры, предназначенной для работы в реальном режиме и возвращающей управление при помощи команды RET FAR.

Регистры на входе
AX      0301h
BH      Байт флагов. Если установлен в единицу бит 0, выполняется 
сброс контроллера и линии A20. Остальные биты зарезервированы 
и должны быть сброшены в нуль.
CX      Количество слов, которые должны быть скопированы из стека 
защищённого режима в стек реального режима.
ES:(E)DI        Адрес управляющей структуры для вызова 
процедуры реального режима.

Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.
ES:(E)DI        Адрес модифицированной (в результате выполнения 
процедуры реального режима) управляющей структуры в формате защищённого режима.




Вызов процедуры реального режима, заканчивающейся командой IRET

Эта процедура позволяет выполнить вызов процедуры, предназначенной для работы в реальном режиме и возвращающей управление при помощи команды IRET.

Регистры на входе
AX      0302h
BH      Байт флагов. Если установлен в единицу бит 0, выполняется 
сброс контроллера и линии A20. Остальные биты зарезервированы и 
должны быть сброшены в нуль.
CX      Количество слов, которые должны быть скопированы из стека 
защищённого режима в стек реального режима.
ES:(E)DI        Адрес управляющей структуры для вызова процедуры 
реального режима.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.
ES:(E)DI        Адрес модифицированной (в результате выполнения 
процедуры реального режима) управляющей структуры в формате защищённого режима.




Перехват передачи управления программе реального режима

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

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

Регистры на входе
AX      0303h
DS:(E)SI        Адрес процедуры в формате защищённого режима, 
которая будет вызвана вместо перехваченной.
ES:(E)DI        Адрес управляющей структуры для вызова процедуры 
реального режима (в формате защищённого режима).
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.
ES:(E)DI        Адрес модифицированной (в результате выполнения 
процедуры реального режима) управляющей структуры в формате защищённого режима.
CX:DX   Адрес вызова перехватываемой программы в формате реального режима.




Процедура защищённого режима, перехватывающая управление, вызывается с запрещёнными прерываниями и получает следующие параметры:

DS:(E)SI Адрес стека реального режима в формате <селектор:смещение>.
ES:(E)DI Адрес управляющей структуры в формате <селектор:смещение>.
SS:(E)SP Стек защищённого режима.

Остальные регистры остаются в неопределённом состоянии.

Для выполнения возврата из процедуры перехвата необходимо выполнить команду IRET, предварительно загрузив регистры следующим образом:

ES:(E)DI        Адрес управляющей структуры  в формате <селектор:смещение>.




Отмена перехвата передачи управления процедуре реального режима.

Эта функция отменяет действие предыдущей.

Регистры на входе
AX      0304h
CX:DX   Адрес вызова перехватываемой программы в формате реального 
режима, для которой отменяется перехват.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.




Получить адреса процедур сохранения/восстановления состояния.

С помощью этой функции программа может сохранять или восстанавливать состояние задачи (в том числе содержимое всех регистров процессора). это бывает необходимо перед изменением реального режима работы на защищённый и обратно.

Регистры на входе
AX      0305h
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.
AX      Размер буфера для сохранения состояния.
BX:CX   Адрес программы сохранения/восстановления для реального режима 
в формате <сегмент:смещение>.
ES:(E)DI        Адрес программы сохранения/восстановления для защищённого 
режима в формате <селектор:смещение>.




Процедура сохранения/восстановления состояния вызывается командой CALL FAR и получает следующие параметры:

ES:(E)DI        Указатель на буфер сохранения состояния.
AL      0 - для сохранения состояния,
1 - для восстановления состояния.




Получить адрес процедуры переключения режима

С помощью этой функции программа может получить адреса процедур для переключения из реального режима в защищённый и из защищённого в реальный.

Регистры на входе
AX      0306h
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.
BX:CX   Адрес программы переключения из реального режима в защищённый 
в формате <сегмент:смещение>.
SI:(E)DI        Адрес программы для переключения из защищённого режима 
в реальный в формате <селектор:смещение>.




Перед переключением режима, которое выполняется командой JMP FAR, необходимо подготовить регистры:

AX Новое содержимое регистра DS.
CX Новое содержимое регистра ES
DX Новое содержимое регистра SS
(E)BX Новое содержимое регистра (E)SP
SI Новое содержимое регистра CS
(E)DI Новое содержимое регистра (E)IP

В процессе переключения режима содержимое регистра (E)BP останется неизменным, поэтому этот регистр можно использовать как указатель.

Для процессоров i80386 и i80486 после переключения режима в регситры FS и GS бует записано нулевое значение.

Получить версию спецификации DPMI

Функция позволяет получить текущую версию DPMI.

Регистры на входе
AX      0400h

Регистры на выходе:
CARRY   0
AH      Верхний (major) номер версии.
AL      Нижний (minor) номер версии.
BX      Байт флагов:
        бит 0 = 1 если программа работает под управлением DPMI 
		для процессора i80386;
        бит 1 = 1 если процессор вернулся в реальный режим для о
		бработки прерывания;
        бит 2 = 1 если в системе поддерживается виртуальная память;
        бит 3  и все остальные зарезервированы для использования в будущем.
CL      Тип процессора:
     02 = i80286
     03 = i80386
     04 = i80486
DH      Текущее значение номера прерывания для IRQ0.
DL      Текущее значение номера прерывания для IRQ8.




Получить информацию о свободной памяти

Регистры на входе
AX      0500h
ES:(E)DI        Адрес бфера размером 30h байт в формате 
<селектор:смещение>.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.
ES:(E)DI        Адрес бфера размером 30h байт в формате 
<селектор:смещение>, заполненного информацией о свободной памяти.




Формат буфера:

Таблица 12. Формат буфера для информации о свободной памяти, получаемой средствами DPMI.

Смещение Описание
00h Размер наибольшего доступного свободного блока в байтах
04h Максимальное количество доступных незаблокированных страниц памяти.
08h Максимальное количество доступных заблокированных страниц памяти.
0Ch Размер линейного адресного пространства в страницах.
10h Общее количество незаблокированных страниц.
14h Количество свободных страниц.
18h Общее количество физических страниц.
1Ch Размер свободного линейного адресного пространства в страницах.
20h Размер страничного файла или раздела в страницах.
24h-2Fh Зарезервировано.

Если текущая реализация DPMI не поддерживает виртуальную память, данная функция заполняет только первое поле структуры. Остальные поля устанавливаются в -1 (0FFFFFFFFh).

Получить блок памяти

Эта функция предназначена для получения программой участка линейной памяти. Для полученного блока памяти не выполняется автоматического создания селектора, программа должна создать селектор самостоятельно.

Регистры на входе
AX      0501h
BX:CX   Размер блока памяти в байтах.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.
BX:CX   Линейный адрес полученного блока.
SI:DI   Индекс полученного блока памяти, нужен для выполнения 
операций с блоком памяти (изменение его размера или освобождение).




Освободить блок памяти

Функция освобождает блок памяти, полученный при помощи предыдущей функции.

Регистры на входе
AX      0502h
SI:DI   Индекс освобождаемого блока памяти.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.




Изменить размер блока памяти

Функция изменяет размер блока памяти, полученного при помощи функции 0501h.

Регистры на входе
AX      0503h
BX:CX   Новый размер блока памяти в байтах.
SI:DI   Индекс изменяемого блока памяти.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.
BX:CX   Новый линейный адрес полученного блока.
SI:DI   Новый индекс блока памяти.




Зафиксировать линейную область памяти

Эта функция фиксирует в памяти область, задаваемую линейным адресом. Для зафиксированной области памяти не выполняется свопинг страниц.

Регистры на входе
AX      0600h
BX:CX   Начальный линейный адрес фиксируемого участка памяти.
SI:DI   Размер фиксируемого блока памяти в байтах.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.




Расфиксирование блока памяти

Эта функция должна быть использована для расфиксирования блока памяти, зафиксированного предыдущей функцией.

Регистры на входе
AX      0601h
BX:CX   Начальный линейный адрес расфиксируемого участка памяти.
SI:DI   Размер расфиксируемого блока памяти в байтах.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.




Отмена фиксации страниц для области памяти виртуального режима

Область памяти, используемая виртуальной машиной, обычно зафиксирована и не подвергается свопингу. С помощью этой функции вы можете разрешить свопинг для заданного участка памяти, принадлежащей виртуальной машине.

Регистры на входе
AX      0602h
BX:CX   Начальный линейный адрес расфиксируемого участка памяти.
SI:DI   Размер расфиксируемого блока памяти в байтах.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.




Фиксация страниц для области памяти виртуального режима

Функция предназначена для отмены действия предыдущей функции. Она фиксирует участок памяти виртуальной машины, отменяя для него свопинг страниц.

Регистры на входе
AX      0603h
BX:CX   Начальный линейный адрес фиксируемого участка памяти.
SI:DI   Размер фиксируемого блока памяти в байтах.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.




Получить размер страницы памяти

Функция возвращает размер страницы памяти в байтах.

Регистры на входе
AX      0604h
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.
BX:CX   Размер страницы памяти в байтах.




Зарезервированные функции

Функции 0700h и 0701h зарезервированы и не должны вызываться вашей программой.

Отметка страницы для свопинга

Функция используется для того, чтобы сообщить операционной системе о возможности выгрузки (свопинга) на диск указанной страницы или диапазона страниц.

Регистры на входе
AX      0702h
BX:CX   Начальный линейный адрес отмечаемых страниц.
SI:DI   Размер отмечаемого блока памяти.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.




Отвергнуть содержимое страниц

Функция отмечает страницы как не содержащие полезной информации. Операционная система может использовать данные страницы для удовлетворения запросов на память.

Регистры на входе
AX      0703h
BX:CX   Начальный линейный адрес страниц, отмечаемых как не 
содержащие полезной информации.
SI:DI   Размер отмечаемого блока памяти в байтах.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.




Преобразование физического адреса в линейный

Функция может быть использована для работы с периферийными устройствами, адресное пространство ввода/вывода которых отображается в диапазон физических адресов.

Регистры на входе
AX      0800h
BX:CX   Физический адрес памяти.
SI:DI   Размер блока памяти в байтах.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.
BX:CX   Линейный адрес памяти.




Запретить виртуальные прерывания

Функция сбрасывает флаг виртуального прерывания и возвращает предыдущее состояние этого флага.

Регистры на входе
AX      0900h
Регистры на выходе:
CARRY   0
AL      0, если виртуальные прерывания были запрещены,
1, если виртуальные прерывания были разрешены.




Разрешить виртуальные прерывания.

Функция устанавливает флаг виртуальных прерываний, разрешая виртуальные прерывания, и возвращает предыдущее сосотояние этого флага.

Регистры на входе
AX      0901h
Регистры на выходе:
CARRY   0
AL      0, если виртуальные прерывания были запрещены,
1, если виртуальные прерывания были разрешены.




Получить состояние флага виртуальных прерываний

Функция позволяет узнать текущее состояние флага виртуальных прерываний.

Регистры на входе
AX      0902h
Регистры на выходе:
CARRY   0
AL      0, если виртуальные прерывания запрещены,
1, если виртуальные прерывания разрешены.




Получить адрес для использования расширений DPMI

DOS-экстендеры могут расширять сервис DPMI своими функциями. Для получения доступа к этим функциям можно использовать функцию 0A00h. Вызывающая программа должна задать в регистрах DS:(E)SI адрес строки, закрытой нулём. Строка должна содержать название производителя DOS-экстендера или другой уникальный идентификатор расширения.

Регистры на входе
AX      0A00h
DS:(E)SI        Указатель на строку, закрытую нулём.
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.
ES:(E)DI        Точка входа для вызова расширений




Содержимое регистров DS, FS, GS, EAX, EBX, ECX, EDX, ESI, и EBP не сохраняется.

Установить точку останова для отладки

Функция позволяет установить отладочную точку останова по заданному линейному адресу.

Регистры на входе
AX      0B00h
BX:CX   Линейный адрес точки останова.
DL      Размер используемого для точки останова операнда (1, 2, или 4 байта).
DH      Тип точки останова
     0 = Выполнение
     1 = Запись
     2 = Чтение/запись
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.
BX      Индекс для доступа к отладочной точке останова




Отмена отладочной точки останова

Функция отменяет точку останова, установленную при помощи предыдущей функции.

Регистры на входе
AX      0B01h
BX      Индекс отладочной точки останова
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.




Получить состояние отладочной точки останова

Функция возвращает состояние отладочной точки останова, определённой при помощи функции 0B00h.

Регистры на входе
AX      0B02h
BX      Индекс отладочной точки останова
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.
AX      Флаги:
   Бит 0 = 1 если произошло выполнение точки останова.




Сброс точки останова

Функция сбрасывает состояние для заданной отладочной точки останова.

Регистры на входе
AX      0B03h
BX      Индекс отладочной точки останова
Регистры на выходе:
CARRY   0, если функция выполнилась без ошибки,
1, если произошла ошибка.




[Назад] [Содеожание] [Дальше]