A un point ou un autre de son execution ,tout client DPMI s'exécute sur quatre piles differentes: une pile d'application, une pile verrouillée en mode protégé , une pile mode réel,et la pile de l'hôte DPMI . Il est important de comprendre comment l'hôte gère ces piles pour bien assimiler l'environnement en mode protégé .

La pile d'application est la première que le client DPMI exécute. C'est initiallement la pile en mode réel que le client emploie avant de basculer en mode prot‚gé, bien que rien ne le previenne apr&eagrave;s le changement de mode . La pile d'application peut ˆtre deverrouillée si desiré. Les interruptions logicielles executées en mode protégé se servent de cette pile.

La pile verrouillée en mode protégé est fournie par l'hôte DPMI. L'hôte bascule automatiquement sur cette pile pendant les interruptions matérielles, interruptions logicielles 1CH, 23H, et 24H,toutes les exceptions, et pendant l'exécution des callbacks mode réel. Les interruptions imbriquées ou les appels ne provoquent pas de changement de pile. Si le client arrète cette pile, la nouvelle doit ˆtre verrouillée et devient la pile en mode protégé jusqu'a ce qu'il revienne en arrière . Lors du retour d'une interruption ou d'un appel, l'hôte bascule sur la pile originale en mode protégé. Notez que l'hôte doit fournir une pile verrouillée d'un d'un minimum de 4 Ko, et que les interruptions logicielles autres que 1CH, 23H, et 24H n'utilisentPAS cette pile.

La pile mode r‚el est ‚galement fournie par l'hote DPMI, et est usuallement situ‚e dans la zone de donn‚es de l'hôte DPMI allou‚e par le client avant so passage en mode protégé. La pile mode r‚el a au moins une taille de 200H octets et est toujours plac‚e en memoire verrouillé. Les interruptions qui sont renvoy‚es au mode r‚el , ainsi que les appels aux gestionnaires d'interruptions en mode r‚el ou les procedures via Int 31H Fonctions 0300H, 0301H, ou 0302H, utilisent cette pile.

La pile de l'hôte DPMI est seulement accessible … l'hôte DPMI; elle est utilis‚e par l'hôte pour gerer les interruptions et exceptions que l'hôte ex‚cute pour le compte du client. Par exemple, quand le client requiert un changement de mode , l' original SS:(E)SP du programme en mode protégé peut ˆtre pr‚serv‚ sur la pile de l'hôte pendant que l'hôte DPMI bascule sur la pile verrouillé en mode protégé.

Il y a quatre maniŠres diff‚rentes pour un client de forcer un changement de mode entre mode protégé et mode r‚el:

Tous ces changements de mode except‚ les "raw" doivent sauvegarder quelque information sur la pile de l'hôte DPMI. Cela signifie que 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 et pile switching during these events.

Clients that use the raw mode switch services et perform nested mode switches must use the DPMI state save/restore functions (whose addresses may be obtained with Int 31H Function 0305H), causing the host to maintain information on the "other" mode's current state. This information includes the CS:(E)IP, SS:(E)SP, et 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 hôte DPMImay preserve the real mode CS:(E)IP, SS:(E)SP, et segment registers on the host pile, causing a return to the wrong address when the handler finally executes the IRET.

Example: 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 mode protégé using the raw mode switch service, et restores the state of the real mode registers using the save/restore function. The mode protégé registers are saved by pushing them on the pile in the usual fashion. The example is intended only to show the logical sequence of execution; in a real program, the real mode et protection mode variables et functions would likely reside in separate segments.


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 mode protégé
					; save/restore state entry point
realrms	dd	0			; far pointer to real mode
					; raw mode switch entry point
protrms dd      0                       ; far pointer to mode protégé
					; raw mode switch entry point

protdw  dw      0                       ; placeholder for mode protégé DS
protip  dw      0                       ; placeholder for mode protégé IP
protcs  dw      0                       ; placeholder for mode protégé CS
protsp  dw      0                       ; placeholder for mode protégé SP
protss  dw      0                       ; placeholder for mode protégé SS
	.
	.
	.

					; this code is executed during
					; application initialization

	mov	ax,305h			; get addresses of DPMI host's
	int	31h			; 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 mode protégé

	mov	ax,306h			; get address of DPMI host's
	int	31h			; 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 mode protégé
					; must also initialize the
                                        ; sp et realss variables
	.
	.
	.

					; this code is executed during
					; program execution
callopenfile proc
        pusha                           ; save mode protégé registers
	push	es

        sub     sp,savsiz               ; alloue space on current pile
	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 mode protégé 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 mode protégé DS
        mov     dx,protss               ; load mode protégé SS
        mov     bx,protsp               ; load mode protégé SP
        mov     si,protcs               ; load mode protégé CS
        mov     di,protip               ; load mode protégé IP
	jmp	realrms

openfile endp