Calling the Real to Protected Mode Switch Entry Point


After using Int 2Fh function 1687h, to obtain the
protected mode entry point, the DPMI client must call
the entry point address as described in this section.

To Call

AX = Flags
Bit 0 = 1 if program is a 32-bit application
ES = Real mode segment of DPMI host data area. This
must be the size of the data area returned in SI
from the previous function. ES will be ignored if
the required data size is zero.
Call the address returned in ES:DI by the previous
function

Returns

If function was successful:
Carry flag is clear.
Program is now executing in protected mode.
CS = 16-bit selector with base of real mode CS and a
64K limit
SS = Selector with base of real mode SS and a 64K limit
DS = Selector with base of real mode DS and a 64K limit
ES = Selector to program's PSP with a 100h byte limit
FS and GS = 0 (if running on an 80386 or 80486)
If the program is a 32-bit application the high word of
ESP will be 0
All other registers are preserved

If function was not successful:
Carry flag is set.
Program is executing in real mode

Programmer's Notes

o Once in protected mode, all Int 31h calls that are
supported by DPMI can be called.
o To terminate the program, execute an Int 21h with
AH=4Ch and AL=Error code. This is the standard
DOS exit function. Do not use any other DOS
termination call -- Only AH=4Ch is supported under
DPMI.
o Under different implementations of DPMI the
privilege ring of a program will change. Programs
should make no assumptions about the ring at which
they will run. When creating descriptors,
programs should set the DPL of the descriptor to
the same ring as their initial code segment. Use
the lar instruction to determine the protection
ring of your program's code segment. All
descriptors created by your program should be set
to the same protection level.
o Programs that specify that they are 32-bit
applications will initially run with a 16-bit code
segment. Stack and data selectors for 32-bit
programs will be 32-bit (the Big bit will be set).
However, all Int 31h calls will require 48-bit
pointers even though the program is running in a
16-bit code segment.
o Unless you have explicitly enabled the A20 address
line through the XMS interface, do not assume that
memory from 1Mb to 1Mb+64K-16 (the High Memory
Area) is addressable once your program is running
in protected mode. If you want to be able to
access the HMA then you must enable the A20
through XMS before entering protected mode. XMS
calls are not supported in protected mode. Note
that this restriction is only important for
software that wishes to access the HMA. Under all
implementations of DPMI the physical A20 address
line will always be enabled while executing
protected mode code. However, some 80386 specific
DPMI implementations simulate 1Mb address wrap for
compatibility reasons. Under these DPMI
implementations, the HMA will not be accessible
unless the A20 is enabled through the XMS
interface.
o The environment pointer in the current program's
PSP will automatically be converted to a
descriptor. If you want to free the program's
environment memory, you must do so before entering
protected mode. In this case, the environment
pointer descriptor will point to garbage and
should not be used. The DPMI client may change
the environment pointer in the PSP after entering
protected mode but it must restore it to the
selector created by the DPMI host before
terminating.
o The caller is allowed to modify or free the DS,
SS, and CS descriptors allocated by this call.
You may not modify the PSP descriptor or
environment pointer descriptor in the PSP.
o Note that if DS=SS on entry to this call then only
one descriptor will be allocated for both DS and
SS. In this case, for example, if you changed the
base of the DS descriptor you would also change
the base of the stack segment.
o For some hosts it may be a good idea for protected
mode programs to use some or all of the real mode
memory allocated to the real mode program by DOS
for protected mode code or data. Protected mode
programs that use memory in the first 1Mb should
mark the memory as pageable using Int 31h 0602h.

Example Code

;
; Get the entry point address and save it
;
mov ax, 1687h
int 2Fh
test ax, ax
jnz Cant_Enter_PMode
mov [PMode_Entry_Seg], es
mov [PMode_Entry_Off], di

;
; Allocate memory for use by DOS extender if necessary
; NOTE: This code assumes that the program has already
; shrunk its memory block so that the DOS
; memory allocation call will work
;
test si, si
jz Enter_PMode_Now
mov bx, si
mov ah, 48h
int 21h
jc Cant_Enter_PMode
mov es, ax

;
; Enter protected mode as a 16-bit program
;
Enter_PMode_Now:
xor ax, ax
call DWORD PTR [PMode_Entry_Off]
jc Cant_Enter_PMode

;
; The program is running in protected mode now!
; Protected mode initialization code would go here.
; Mark program's real mode memory as pageable, etc.
;
.
.
.

;
; Quit the program and return to real mode DOS
;
mov ax, 4C00h
int 21h