⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xlib.doc

📁 DOS保护模式下汇编程序设计.zip
💻 DOC
📖 第 1 页 / 共 5 页
字号:
  CSEGSEL          CSEG              XLIB 16-bit code segment
  CSEGDSEL         CSEG              Data selector to CSEG
  TSEGSEL          TSEG              32-bit code segment
  TSEGDSEL         TSEG              Data selector to TSEG
  DSEGSEL          DSEG              XLIB data segment
  FLATSEL          .                 Flat-model code selector
  FLATDSEL         .                 Flat-model data selector
  DGROUPSEL        DGROUP            DGROUP data group
  SCRNSEL          .                 Screen data (color or monochrome)
  -----------------------------------------------------------------------------


       The flat-model and TSEG descriptors have limit FFFFFFFFH.  All other
  descriptors have limit FFFFH.  The screen descriptor has base set to B8000H
  for color monitors and B0000H for monochrome monitors.  The data descriptors
  have their big bits set; consequently, implicit stack instructions will use
  ESP rather then SP.  All code segments are readable and nonconforming.



                                        3






  Descriptor privilege levels and requested privilege levels are set to zero
  unless DPMI is installed.  Privilege levels under DPMI will be dictated by the
  DPMI host, but will generally be set to three.
       The values contained in the above selectors will be different under DPMI
  than other environments.  Moreover, DPMI selectors values can differ under
  different DPMI environments depending upon the DPMI host and the presence of
  other DPMI clients.  The user should therefore always read selector values
  from these locations.
       Since selectors are contained in DSEG, the user must never lose track of
  the DSEG selector.  This could prove a problem in interrupt handlers where no
  assumptions can be made as to segment register contents.  Consequently, XLIB
  places a copy of the DSEG selector in TSEG where it can always be found.  It
  is stored under WORD symbol CSDSEGSEL and may be read with CS segment
  override.  For example from TSEG code you can always load DS with DSEGSEL
  using MOV DS,CS:CSDSEGSEL.
       TSEG may be larger than 64K provided that certain rules are observed.
  First, only 32-bit protected-mode code should be placed in TSEG.  The
  processor will not generally be able to execute real-mode code in this segment
  because the offsets will be 32-bit values.  Second, real-mode code should
  never write to or read from TSEG.  Such instructions will also require 32-bit
  offsets.  If you need to make modifications to TSEG, then do them from a TSEG
  protected-mode procedure.  Finally, never encode segment constants in TSEG.
  For example, the symbols CSEG, TSEG, DSEG, and DGROUP should never be found in
  TSEG.  DOS will not be able to perform relocation fixups on these constants if
  they are in a segment larger than 64K.  To read these values from TSEG,
  initialize memory locations in a 16-bit segment to the values and then read
  the memory locations.  Memory locations in DSEG have already been initialized
  for XLIB segments.  See Appendix A.





























                                        4






                                3. Mode Switching


       As illustrated in Example 1, CALLPM may be used to transfer control to
  protected mode.  When execution is returned to real mode after CALLPM, only
  segment registers and ESP are restored to their original values.  Real mode
  receives other registers (except EFLAGS) at values as of the protected-mode
  RET instruction.  Control may be returned from protected mode to real mode
  either by RET or by a near jump to RETPM (return from protected mode).  RETPM
  is an XLIB procedure which successfully returns control to real mode
  regardless of stack state.
       Execution may also be transferred to protected mode with the ENTERPM
  (enter protected mode) procedure.  This procedure is specially designed to
  accommodate mixed language programming with high-level languages operating in
  real mode.  High-level language modules may be linked with libraries
  containing protected-mode procedures.  These procedures may then be called
  from high-level code.  However, such procedures must generally be careful to
  preserve register state.  ENTERPM restores register state as required by
  Microsoft high-level languages.  In particular, ENTERPM restores all 16-bit
  and 32-bit registers (including system and control flags in EFLAGS) except EAX
  and EDX.  EAX and EDX are not restored since these are typically used by high-
  level languages for return values.  ENTERPM otherwise functions exactly as
  CALLPM.
       Both CALLPM and ENTERPM save register state as of call; however, upon
  return to real mode, CALLPM restores only segment registers and ESP while
  ENTERPM restores all registers except EAX and EDX.  CALLPM and ENTERPM will
  also save and restore the state of the floating point unit (FPU) if requested.
  FPU save/restore can be enabled by setting bit 2 of OFLAGS (operation flags).
  The bit is clear by default.  OFLAGS is a public WORD in DSEG.
       FPU state is saved with the FSAVE instruction executed from real mode.
  This instruction resets the FPU; consequently, the FPU control word must be
  redefined.  XLIB will therefore load FPUCW (FPU control word) to the FPU
  control word after performing FSAVE.  FPUCW is a public WORD location in DSEG.
  FPU state is restored with the FRSTOR instruction executed in real mode.
       Control may be returned to real mode after ENTERPM either with the RET
  instruction or by a near jump to EXITPM.  EXITPM will return control to real
  mode regardless of stack state.
       The return address placed on the stack by CALLPM is actually a near
  return to RETPM.  Likewise, ENTERPM places a near return to EXITPM.  CALLPM
  and ENTERPM are otherwise identical procedures.  EXITPM restores all registers
  except EAX and EDX.  RETPM restores only segment registers and ESP.
       CALLPM and ENTERPM save registers to public locations in DSEG.  The
  following table specifies the symbols under which the registers are stored.
  The calling stack is always saved after the real-mode return address and the
  protected-mode target address have been popped from it.












                                        5






  Table 2:  CALLPM/ENTERPM Register Storage Locations by Public Symbol
  -----------------------------------------------------------------------------
  Register           Symbol              Symbol Type
  EBX                ORGEBX              DWORD
  ECX                ORGECX              DWORD
  ESI                ORGESI              DWORD
  EDI                ORGEDI              DWORD
  EBP                ORGEBP              DWORD
  ESP                ORGESP              DWORD
  EFLAGS             ORGEFLAGS           DWORD
  SS                 ORGSS               WORD
  DS                 ORGDS               WORD
  ES                 ORGES               WORD
  FS                 ORGFS               WORD
  GS                 ORGGS               WORD
  FPU State          ORGFPU              BYTE[94]
  -----------------------------------------------------------------------------


       The protected-mode targets of CALLPM and ENTERPM receive the XLIB
  protected mode stack (SS = TSEGSEL) with 1000H bytes of free space.  The
  target also receives DS = FLATDSEL (flat-model data selector), ES = TSEGDSEL
  (TSEG data selector), FS = DSEGSEL (DSEG selector), and GS = DGROUPSEL (DGROUP
  selector).  The target procedure may switch stacks if desired.
       Once within protected mode, far procedures in real mode can be called
  using CALLRM (call real mode), which is a near procedure in TSEG.  CALLRM
  should be called with the real-mode target address on the stack (push segment
  first)  CALLRM saves and restores only segments registers and ESP.  The target
  address receives the XLIB real-mode stack (SS = DSEG) with 200H free bytes, DS
  = DGROUP, and ES = DSEG.  Code called by this routine cannot perform XLIB
  shifts back to protected mode.  This excludes usage of the XLIB memory
  management procedures and XLIB interrupt-vector management procedures since
  these require protected-mode execution.
       CALLRM saves segment registers and ESP at public locations in DSEG.  The
  following table specifies the symbols under which the registers are stored.
  The calling stack is saved after popping the protected-mode near return and
  the real-mode target address.


  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
  -----------------------------------------------------------------------------








                                        6






                             4. Interrupt Management


       XLIB handles nearly all interrupts occurring in protected mode by
  shifting to real mode and calling the inherited real-mode interrupt handlers.
  All interrupts are handled this way except the keyboard interrupt (IRQ 1) and
  the FPU interrupt (IRQ 13).  XLIB has its own handlers for these routines.
  These handlers are activated as of protected-mode entry through CALLPM or
  ENTERPM.  They remain active during calls back to real mode through CALLRM.
  They are disabled upon return to CALLPM/ENTERPM.  The user may replace or
  disable these handlers if desired.
       It is generally desirable for the user to be able to terminate a program
  or subroutine with a certain keypress combination.  Unfortunately, it is
  difficult to safely abort protected-mode execution from an interrupt handler.
  This is particularly the case under DPMI.  The DPMI host traps all interrupts
  before transferring control to the interrupt handler.  If control is not
  returned back to the host with an IRET instruction, the host will be left in
  an irregular and potentially unstable state.  Similar problems could occur
  under a VCPI multitasking control program.  Consequently, a keyboard interrupt
  handler cannot be safely used to immediately abort execution upon a keypress.
       The XLIB keyboard interrupt handler provides the best alternative.  The
  handler examines keyboard input to determine if a user definable hot key has
  been pressed.  If a pressed key is not the hot key, the interrupt handler
  cascades the interrupt to the inherited real-mode handler.  If the hot key is
  pressed, then a flag is placed in a DWORD condition code whose linear address
  is stored in CCODEPTR (condition code pointer).  CCODEPRR is a public DWORD in
  DSEG.  The condition code may then be polled by code in the main thread of
  execution where termination can be safely accomplished.  The hot key is not
  cascaded.
       The hot key specification is stored in DSEG at a public WORD location
  called HOTKEY.  The lower byte of HOTKEY contains the scan code of the hot key
  while the upper byte specifies the state of the shift keys.  Bit 8 specifies
  the state of SHIFT; bit 9 specifies CTRL, and bit 10 specifies ALT.  All other
  bits are ignored.  Set bits require that the designated shift key be pressed.
  The default setting for HOTKEY is 022EH (CTRL C).  The condition code flag for
  the hot key is included among XLIB error codes in Appendix C.
       By default CCODEPTR contains the linear address to public DWORD location
  CCODE which is in DSEG.  Therefore, the hot key flag would be written to CCODE
  by default.  CCODEPTR may be changed by the user; however, it must point to an
  address in conventional memory.
       The XLIB interrupt handler for the FPU performs three functions upon the
  occurrence of any FPU exception that is unmasked in the FPU control word.
  First, an error code is loaded to EAX and is also recorded at the linear
  address in CCODEPTR.  Next, the FPU is initialized with FNINIT (the FPU
  control word is preserved).  Third, control is transferred to EXITPM to return
  to real mode.  The high word stored in EAX and the condition code will be the
  FPU status word.  This word may be examined to determine the nature of the
  exception.
       The response of the FPU to exception conditions is largely determined by
  the settings in the FPU control word.  If FPU save/restore is enabled, then
  the FPU control word will be set to FPUCW upon execution of CALLPM/ENTERPM.
  The default value for FPUCW is 0332H.  This sets rounding control to nearest,
  precision control to 64 bits, and unmasks exceptions for overflow, zero
  divide, and invalid operations.  Exceptions for underflow, precision, and



                                        7






  denormalized operations are masked, and are therefore handled internally by
  the FPU.  FPUCW may be modified by the user.
       As explained above, the machine may be left in an unstable state after
  code has been terminated from within an interrupt handler.  This is also the
  case for the FPU interrupt handler.  If an FPU exception occurs under DPMI or
  under a VCPI-based multitasker, then the machine may need rebooting.  Most
  DPMI hosts appear to be restored to normal state by execution of INT 21
  function 4CH (DOS termination).  However, this approach is not recommended in
  the DPMI specifications, and should be particularly suspect under a
  multitasker.  It is generally safe to continue execution after an FPU
  exception when running in a single-task environment under VCPI or when running
  in the absence of both DPMI and VCPI.  The user may therefore wish to debug
  FPU code in these sorts of environments.
       Bit 0 of OFLAGS is used by XLIB to simultaneously enable or disable all
  of its own interrupt handlers.  Setting the bit enables the handlers.  XLIB
  sets this bit upon calls to CALLPM/ENTERPM and clears the bit upon return.
  All interrupts are cascaded to the inherited real-mode handlers when the bit
  is clear.
       The keyboard interrupt handler may be permanently disabled by setting
  HOTKEY to zero.  This follows since no key has a zero scan code.  With HOTKEY
  = 0, all keyboard interrupts are cascaded to the inherited real-mode handler.
       The FPU exception handler may be permanently disabled by setting bit 1 in
  OFLAGS.  If this bit is set, then the FPU interrupt handler simply cascades
  the interrupt to the inherited real-mode handler.  XLIB will set the bit
  during initialization if an FPU is not present; it is otherwise cleared.
       Real-mode software interrupts which receive or return values in segment
  registers cannot be used within protected mode because the deflection routine
  will restore selectors to segment registers upon completion of the interrupt.
  To use such software interrupts, one must switch to real mode through CALLRM;
  issue the interrupt, and then transfer the segment registers to other
  registers before returning to protected mode.
       The user may install real-mode interrupt handlers in usual fashion.  Such
  handlers will also receive interrupts occurring in protected mode provided
  that the protected-mode handlers cascade the interrupt.  Protected-mode
  interrupts will be deflected to real mode either by XLIB or by the DPMI host.
  If XLIB deflects the interrupt, then the handler will receive SS = DSEG with
  ESP set to 200H free bytes.  Stack sizes under DPMI will depend upon the host.
       The DOS routines to get and set interrupt vectors (INT 21H functions 35H
  and 25H) receive and return values through segment registers; consequently,
  they cannot be used in protected mode.  Instead, use the XLIB procedures
  PMGETRMIV and PMSETRMIV (protected mode - get/set real-mode interrupt vector).
  Call PMGETRMIV with the interrupt number in AL.  The handler address is
  returned in CX:DX.  Call PMSETRMIV with the interrupt number in AL and the new
  handler address in CX:DX.
       The user may install a protected-mode interrupt handler from real mode by
  calling SETPMIV (set protected-mode interrupt vector).  Call with the
  interrupt number in AL and the address of the new handler in CX:EDX (CX is a
  selector).  This routine returns an error code in EAX (EAX returned as zero if
  successful).  The current protected-mode interrupt vector may be obtained by
  calling GETPMIV.  Call with AL equal to the interrupt number.  The current
  handler address is returned in CX:EDX.  This routine is always successful.
  These routines should not be used to manage vectors for CPU exceptions when
  DPMI is active.  Direct calls to DPMI functions should be executed for these

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -