[Назад] [Далее] | ![]() |
Вызов любого программного прерывания, кроме INT 31h и INT 21h/АН = 4Ch (функция DPMI: завершение программы), приводит к тому, что DPMI-сервер переключается в режим V86 и вызывает это же самое прерывание, скопировав все регистры, кроме сегментных регистров и стека (состояние сегментных регистров не определено, а стек предоставляет сам DPMI-сервер). После того как обработчик прерывания возвратит управление, DPMI-сервер возвратиться в защищенный режим и вернет управление программе. Таким способом можно вызывать все прерывания, передающие параметры только в регистрах, например проверку нажатия клавиши или вывод символа на экран. Чтобы вызвать прерывание, использующее сегментные регистры, например вывод строки на экран, а также в других ситуациях, требующих вызова процедуры, работающей в другом режиме, применяются следующие функции.
INT 31h, AX = 0300h — Вызов прерывания в реальном режиме
Ввод: | АХ = 0300h ВН = 0, BL = номер прерывания СХ = число слов из стека защищенного режима, которое будет скопировано в стек реального режима и обратно ES:EDI = селектор:смещение структуры регистров v86_regs (см. ниже) |
Вывод: | если CF = 0, структура в ES:EDI модифицируется |
Значения регистров CS и IP в структуре v86_regs игнорируются. Вызываемый обработчик прерывания должен восстанавливать стек в исходное состояние (например, INT 25h и INT 26h этого не делают).
INT 31h, АХ = 0301Н Вызов дальней процедуры в реальном режиме
Ввод: | АХ = 0301h ВН = 0 СХ = число слов из стека защищенного режима, которое будет скопировано в стек реального режима и обратно ES:EDI = селектор:смещение структуры регистров v86_regs (см. ниже) |
Вывод: | если CF = 0, структура в ES:EDI модифицируется |
Вызываемая процедура должна заканчиваться командой RETF.
INT 31h, AX = 0302h Вызов обработчика прерывания в реальном режиме
Ввод: | АХ = 0302h ВН = 0 СХ = число слов из стека защищенного режима, которое будет скопировано в стек реального режима и обратно ES:EDI = селектор:смещение структуры регистров v86_regs (см. ниже) |
Вывод: | если CF = 0, структура в ES:EDI модифицируется |
Вызываемая процедура должна заканчиваться командой IRET.
Эти три функции используют следующую структуру данных для передачи значений регистров в реальный режим и обратно:
+00h: 4 байта — EDI
+04h: 4 байта — ESI
+08h: 4 байта — ЕВР
+0Ch: 4 байта — игнорируются
+10h: 4 байта — ЕВХ
+14h: 4 байта — EDX
+18h: 4 байта — ЕСХ
+1Сh: 4 байта — ЕАХ
+20h: 2 байта — FLAGS
+22h: 2 байта — ES
+24h: 2 байта — DS
+26h: 2 байта — FS
+28h: 2 байта — GS
+2Ah: 2 байта — IP
+2Ch: 2 байта — CS
+2Eh: 2 байта — SP
+30h: 2 байта — SS
Значения SS и SP могут быть нулевыми, тогда DPMI-сервер сам предоставит стек для работы прерывания.
Кроме этих трех функций, которые передают управление процедурам в реальном режиме из защищенного, существует механизм, позволяющий делать в точности обратное действие — передавать управление процедурам в защищенном режиме из реального.
INT 31h, АХ = 0303h — Выделить точку входа для вызова из реального режима
Ввод: | АХ = 0303h DS:ESI = селектор:смещение процедуры в защищенном режиме (заканчивающейся IRET), которую будут вызывать из реального режима ES:EDI = селектор:смещение структуры v86_regs, которая будет использоваться для передачи регистров |
Вывод: | если CF = 0, CX:DX = сегмент:смещение точки входа |
При передаче управления в такую процедуру DS:ESI указывает на стек реального режима, ES:EDI — на структуру v86_regs, SS:ESP — на стек, предоставленный DPMI-сервером, и остальные регистры не определены.
Количество точек входа, которыми располагает DPMI-сервер, ограничено, и неиспользуемые точки входа должны быть удалены при помощи следующей функции DPMI.
INT 31h, AX = 0304h — Освободить точку входа для вызова из реального режима
Ввод: | АХ = 0304h CX:DX = сегмент:смещение точки входа |
Вывод: | CF = 0, если точка входа удалена |