📄 xlib.doc
字号:
Table 3: CALLRM Register Storage Locations by Public Symbol
-----------------------------------------------------------------------------
Register Symbol Symbol Type
-------- ------ -----------
ESP CALLESP DWORD
SS CALLSS WORD
DS CALLDS WORD
ES CALLES WORD
FS CALLFS WORD
GS CALLGS WORD
-----------------------------------------------------------------------------
12
5. Inline Mode Switching
XLIB includes two routines to perform mode switching in C programs using
inline assembly. These procedures are very versatile and simple. A third
routine is included to facilitate calls from 16-bit segments to 32-bit near
procedures in TSEG.
Call INLINEPM to switch to protected mode. Descriptors are automatically
created for CS, SS, and DS. These registers are returned containing selectors
to the respective descriptors. ES is returned containing DSEGSEL. ES may be
used to load other XLIB selectors to segment registers.
Call INLINERM to return to real-mode. This function should be called
from the same segment as the previous call to INLINEPM and should be using the
same stack segment. INLINERM restores segment registers to values which
existed as of the call to INLINEPM.
The following Microsoft C 7.0 program illustrates the usage of these
procedures. The program contains a C subroutine called "getextmem" which uses
INLINEPM and INLINERM to retrieve a DWORD from extended memory.
Observe that since the inline assembly code is in a 16-bit segment,
prefixes must be used with 32-bit instructions. Also observe that INLINERM is
called indirect through a supplied pointer in DSEG called INLINERMPTR. This
is done to ensure that the intersegment call loads CS with the protected-mode
selector for CSEG (CSEGSEL) rather than with the segment constant.
This program may fail if an attempt is made to access logical addresses
which are either protected or undefined in the page tables.
Example 2: Using INLINEPM/INLINERM in C
-----------------------------------------------------------------------------
#include <stdio.h>
#include <xlib.h>
#define som _emit 0x66 /* switch operand mode */
#define sam _emit 0x67 /* switch address mode */
long __far getextmem(long address);
int goterr = 0; /* error flag */
main()
{
long l;
l = INITXLIB(); /* initialize XLIB */
if(l != 0)
{
printf("Library initialization error: %lX\n",l);
return 0;
}
l = getextmem(0x100000); /* read first address in 2ond meg */
if(goterr != 0)
{
printf("Inline mode-switch error: %lX\n",l);
return 0;
}
printf("%lX\n",l);
}
13
long __far getextmem(long address)
{
__asm
{
som ;mov eax,[bp+6]
mov ax,[bp+6] ; ""
call INLINEPM
jc error ;Error code in ax
mov ds,es:FLATDSEL
sam ;push dword ptr [eax]
som ; ""
_emit 0ffh ; ""
_emit 030h ; ""
pop ax
pop dx
call es:INLINERMPTR
jmp done
error:
xor dx,dx ;Return error code in dx:ax
inc goterr
done:
}
}
-----------------------------------------------------------------------------
Detailed Specifications
INLINEPM (Inline Protected-Mode)
Purpose: Return to real-mode caller in 16-bit protected mode.
CPU Mode: Real
Registers at Call: None
Return Registers:
CF clear if successful. Descriptors are created for CS, SS, and DS. These
descriptors have base addresses matching the calling contents of the
respective segment registers. The segment registers are returned containing
selectors to these descriptors. These selectors are also stored in DSEG at
the public WORD locations ILCSSEL, ILSSSEL, and ILDSSEL. See Chapter 2 for
further details as to descriptor specifications. ES, FS, and GS are returned
containing DSEGSEL. Protected mode receives other registers, except the
status flags, at values as of call.
CF set if unsuccessful. The processor will still be in real mode.
Unsuccessful execution can occur only under DPMI. EAX is returned with an
error code. AX = XLIB error code. The high word of EAX will equal a DPMI 1.0
error code (if provided by host). Other registers, except the status flags,
are unchanged.
Details:
INLINEPM stores segment registers at the same locations used by CALLPM and
ENTERPM (Table 1). INLINERM (see below) then restores these registers. C
will require that other registers be preserved also; however, the user is
responsible for managing these.
14
XLIB hardware interrupt handlers are not activated by this procedure (see
Chapter 6). The keyboard handler may be enabled by the user if hot key
detection is needful; however, the FPU exception handler should never be
enabled. Therefore, hot key detection should be enabled by setting both bits
0 and 1 in OFLAGS.
SP is preserved through the mode switch; however, the high word of ESP is
set to zero. The high word must be cleared since SS is set to a descriptor
having FFFFH limit and having its big bit set.
If multiple calls are made to INLINEPM with the same values in CS, SS, and
DS, then descriptors are created only on the first call. Subsequent calls
will therefore execute more quickly.
INLINERM (Inline Real-Mode)
Purpose: Return to 16-bit protected-mode caller in real mode.
CPU Mode: 16-bit protected mode
Registers at Call: CS and SS must equal values as of return from INLINEPM.
Return Registers: Segment registers are restored to values existing as of
former call to INLINEPM. Real mode receives other registers, except status
flags, at values as of call.
Details:
Since INLINERM will be called intersegment, caution must be taken that CS
is loaded with CSEGSEL and not CSEG. XLIB provides a far pointer to this
procedure called INLINERMPTR which may be used to execute the call.
INLINERM and CALL32 are the only 16-bit protected-mode procedures in XLIB.
They are also the only protected-mode procedures having far returns.
CALL32 (Call 32-bit Protected-Mode)
Purpose: Call a 32-bit protected-mode near procedure in segment TSEG from 16-
bit protected-mode.
CPU Mode: 16-bit protected mode
Registers at Call: SS:ESP = 32-bit protected-mode target offset.
Return Registers: All registers, including status flags, are returned with
values existing as of the 32-bit RET instruction.
Details:
CALL32 is a far procedure; therefore, caution must be taken that calls to
CALL32 load CS with CSEGSEL instead of CSEG. XLIB provides a far pointer to
this procedure in DSEG called CALL32PTR which may be used to execute the call.
CALL32 and INLINERM are the only 16-bit protected-mode procedures in XLIB.
They are also the only protected-mode procedures having far returns.
This procedure does not alter the state of OFLAGS.
15
6. Interrupt Management
Interrupt management is the most complicated task performed by XLIB.
Accordingly, this chapter is the most difficult section of the user's manual.
In general, this chapter may be ignored for programs which do not install
interrupt handlers, do not require hot key detection, and do not use floating
point operations.
XLIB Interrupt Handlers
XLIB handles nearly all interrupts occurring in protected mode by
shifting to real mode and calling the currently installed real-mode interrupt
handlers. In all but three cases, XLIB uses inherited real-mode handlers.
XLIB installs its own handlers only for the DOS interrupt (INT 21H), the
keyboard interrupt (INT 9), and the FPU interrupt (INT 75H).
The DOS interrupt handler (INT 21H) intercepts all DOS calls and
determines if termination is requested (AH = 4CH). If not, then the interrupt
is immediately cascaded to DOS. If so, then XLIB performs housecleaning
before relaying the request to DOS. Under DPMI, XLIB will restore all
interrupt vectors and release all allocated descriptors. The DPMI host
automatically releases all allocated memory. Under other configurations, XLIB
will reset all real-mode interrupt vectors and release all allocated extended
memory.
INT 21H function 4CH may be executed in either real mode or protected
mode. DPMI hosts will expect this function to be executed from protected
mode; consequently, XLIB will switch to protected mode before relaying the
request to DPMI. XLIB also installs a protected-mode handler for INT 21H
under DPMI. This is to ensure that XLIB will see the termination request
before the DPMI host.
The keyboard interrupt handler is intended to facilitate termination of
protected-mode procedures with a keypress. When a user-defined hot key is
pressed, the keyboard interrupt handler will modify a flag variable. This
flag variable may then be polled periodically in the main thread of execution.
The keyboard interrupt handler is a real-mode routine.
The inconvenience of having to poll the flag variable is unfortunately
necessary. It is not generally safe to terminate within a hardware interrupt
handler, particularly in protected-mode environments. A hardware interrupt
generated by a keypress may have interrupted system software in the middle of
a system maintenance operation. Termination in such cases would likely leave
the system in an irregular and potentially unstable state.
Matters are further complicated in most protected-mode environments. For
example, a DPMI host will trap all hardware interrupts before cascading them
to interrupt handlers. If control is not returned to the host with the IRET
instruction, then the host will be left in an irregular state. Moreover, the
trapping procedure will likely switch stacks before relaying the interrupt to
the handler; consequently, the handler cannot determine the final return
address and therefore cannot change this address to a termination procedure.
These complications will nearly always occur when hardware interrupts are
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -