Files
oldlinux-files/study/sabre/os/files/ProtectedMode/DPMI1.0Spec/ch4.3.html
2024-02-19 00:25:23 -05:00

210 lines
8.2 KiB
HTML

At one point in its execution or another, every DPMI client runs on
four different stacks: an application stack, a locked protected mode
stack, a real mode stack, and a DPMI host stack. It is important to
understand how the host maintains these stacks to fully understand the
protected mode environment.<p>
The <i>application stack</i> is the primary stack that the DPMI client
executes on. It is initially the real mode stack that the client was
on when it switched into protected mode, although nothing prevents the
client from switching protected mode stacks at any point after the
initial mode switch. Th application stack can be unlocked if desired.
Software interrupts executed in protected mode are reflected on this
stack.<p>
The <i>locked protected mode stack</i> is provided by the DPMI host.
The host automatically switches to this stack during servicing of
hardware interrupts, software interrupts 1CH, 23H, and 24H, all
exceptions, and during the execution of real mode callbacks.
Subsequent nested interrupts or calls will not cause a stack switch.
If the client switches off this stack, the new stack must also be
locked and will become the protected mode stack until it switches
back. When the interrupt or call returns, the host switches back to
the original protected mode stack. Note that the host must provide a
minimum of one 4 KB locked stack, and that software interrupts other
than 1CH, 23H, and 24H do <i>not</i> use this stack. (Refer Appendix
D for descriptor usage rule of locked stack.)<p>
The <i>real mode stack</i> is also provided by the DPMI host, and is
usually located in the DPMI host data area allocated by the client
prior to its initial switch into protected mode. The real mode stack
is at least 200H bytes in size and is always located in locked memory.
Interrupts that are reflected to real mode, as well as calls to real
mode interrupt handlers or procedures via <a
href="api/310300.html">Int 31H Functions 0300H</a>, <a
href="api/310301.html">0301H</a>, or <a
href="api/310302.html">0302H</a>, will use this stack.<p>
A <i>DPMI host stack</i> is only accessible to the DPMI host; it is
used by the host to handle interrupts and exceptions that occur while
the host is executing on behalf of the client. For example, when the
client requests a mode switch, the original SS:(E)SP of the protected
mode program can be saved on the host stack while the DPMI host
switches onto the locked protected mode stack.<p>
There are four different ways that a client can force a mode switch
between protected and real mode:
<ul>
<li> Execute the default interrupt reflection handler (all interrupts
other than Int 31H and Int 21H Function 4CH are initialized by the
DPMI host to point to a handler that reflects the interrupt to real
mode);<p>
<li> Use the DPMI translation services (<a href="api/310303.html">Int
31H Function 0303H</a>, <a href="api/310301.html">0301H</a>, and <a
href="api/310302.html">0302H</a>) to call a real mode interrupt
handler or procedure;<p>
<li> Allocate a real mode callback address with <a
href="api/310303.html">Int 31H Function 0303H</a>; when a real mode
program transfer control to the callback address, the DPMI host will
switch the CPU from real mode into protected mode;<p>
<li> Use the DPMI raw mode switch functions, whose addresses are
obtained with <a href="api/310306.html">Int 31H Function 0306H</a>.<p>
</ul>
All of these mode switches except for the raw mode switches may save
some information on the DPMI host's stack. This means that clients
should not terminate within nested mode switches unless they are using
the raw mode switching services. However, even clients that use raw
mode switches should not attempt to terminate from a hardware
interrupt or exception handler or real mode callback because the DPMI
host performs automatic mode and stack switching during these
events.<p>
Clients that use the raw mode switch services and perform nested mode
switches must use the DPMI state save/restore functions (whose
addresses may be obtained with <a href="api/310305.html">Int 31H
Function 0305H</a>), causing the host to maintain information on the
"other" mode's current state. This information includes the CS:(E)IP,
SS:(E)SP, and other segment register contents; values that the client
has no way to access directly. For example, during the service of a
hardware interrupt that occurs in real mode, the DPMI host may
preserve the real mode CS:(E)IP, SS:(E)SP, and segment registers on
the host stack, causing a return to the wrong address when the handler
finally executes the IRET.<p>
<b>Example:</b> This example illustrates code that saves the state of
the real mode registers using the DPMI save/restore function, switches
to real mode using the raw mode switch service, issues a DOS call to
open a file, switches back to protected mode using the raw mode switch
service, and restores the state of the real mode registers using the
save/restore function. The protected mode registers are saved by
pushing them on the stack in the usual fashion. The example is
intended only to show the logical sequence of execution; in a real
program, the real mode and protection mode variables and functions
would likely reside in separate segments.
<pre>
savsiz dw 0 ; size of state information
realsrs dd 0 ; far pointer to real mode
; save/restore state entry point
protsrs dd 0 ; far pointer to protected mode
; save/restore state entry point
realrms dd 0 ; far pointer to real mode
; raw mode switch entry point
protrms dd 0 ; far pointer to protected mode
; raw mode switch entry point
protdw dw 0 ; placeholder for protected mode DS
protip dw 0 ; placeholder for protected mode IP
protcs dw 0 ; placeholder for protected mode CS
protsp dw 0 ; placeholder for protected mode SP
protss dw 0 ; placeholder for protected mode SS
.
.
.
; this code is executed during
; application initialization
mov ax,305h ; get addresses of DPMI host's
<a href="api/310305.html">int 31h</a> ; state save/restore entry points
mov savsiz,ax ; save state info buffer size
mov word ptr realsrs,cx ; BX:CX = state save/restore
mov word ptr realsrs+2,bx ; entry point for real mode
mov word ptr protsrs,di ; SI:DI = state save/restore
mov word ptr protsrs+2,si ; entry point for protected mode
mov ax,306h ; get address of DPMI host's
<a href="api/310306.html">int 31h</a> ; raw mode switch entry points
mov savsiz,ax ; save state info buffer size
mov word ptr realrms,cx ; BX:CX = raw mode switch
mov word ptr realrms+2,bx ; entry piont for real mode
mov word ptr protrms,di ; SI:DI = raw mode switch
mov word ptr protrms+2,si ; entry point for protected mode
; must also initialize the
; sp and realss variables
.
.
.
; this code is executed during
; program execution
callopenfile proc
pusha ; save protected mode registers
push es
sub sp,savsiz ; allocate space on current stack
mov di,sp ; to save real mode state
mov ax,ss ; set ES:DI = address of buffer
mov es,ax ; to receive state information
xor al,al ; AL=0 for save state request
call protsrs ; call state save/restore routine
mov protds,ds ; save current DS for switch back
mov protss,ss ; save current SS
mov protsp,sp ; save current SP
mov protip,offset returnfromreal ; save return IP
mov protcs,cs ; save return CS
mov ax,seg filename ; load real mode DS
mov ds,realss ; load real mode SS
mov bx,realsp ; load real mode SP
mov si,seg openfile ; load real mode CS
mov di,offset openfile ; load real mode IP
jmp protrms ; go to openfile
returnfromreal:
mov ax,ss ; let ES:DI = address of buffer
mov es,ax ; holding state information
mov di,sp
mov al,1 ; AL=1 to restore state
call protsrs ; call state restore routine
add sp,savsiz ; discard state info buffer
pop es
popa ; restore protected mode registers
ret
callopenfile endp
.
.
.
; this code is executed in real mode
openfile proc
mov dx,offset filename
mov ah,3dh ; issue Open File DOS call
int 21h
jc openerr ; check for error (not shown here)
mov filehandle,bx ; save file handle
mov ax,protds ; load protected mode DS
mov dx,protss ; load protected mode SS
mov bx,protsp ; load protected mode SP
mov si,protcs ; load protected mode CS
mov di,protip ; load protected mode IP
jmp realrms
openfile endp
</pre>