www.pudn.com > DOS保护模式下汇编程序设计.zip > EXAMPLE2.ASM


;The following library should be combined with XLIB.LIB using the Microsoft 
;LINK and LIB utilities.  If BASIC is to be executed from the QBX 
;environment, then a quick library must be loaded with the environment.  See 
;BASIC documentation for instructions. 
 
 
               .MODEL         LARGE,PASCAL 
               .386P 
 
               INCLUDE        XLIB.INC 
 
CSEG           SEGMENT PARA PUBLIC USE16 'CODE' 
               ASSUME CS:CSEG, DS:DSEG 
 
;Function to calculate linear address from segment address on stack. 
;Returns linear address in DX:AX. 
LINADR         PROC FAR PUBLIC, 
               SEGADR:DWORD                  ;Segment address of variable 
               XOR            EAX,EAX        ;Clear high words 
               XOR            EDX,EDX 
               MOV            AX,WORD PTR SEGADR[0] 
               MOV            DX,WORD PTR SEGADR[2] 
               SHL            EDX,4          ;Calculate linear address 
               ADD            EDX,EAX 
               MOV            AX,DX 
               SHR            EDX,16         ;Return linear address in DX:AX 
               RET 
LINADR         ENDP 
 
;Structure defining control block for SUMARRAY. 
ARRAYDATA      STRUCT 
  CONDCODE     DWORD          0              ;Condition code 
  N            DWORD          0              ;Number of elements to sum 
  ADDRESS      DWORD          0              ;Address of first element 
  SUM          DWORD          0              ;Sum of array elements 
ARRAYDATA      ENDS 
 
;Real-mode interface to SUMARRAY32.  Segment address of control block having 
;structure ARRAYDATA should be on the stack. 
SUMARRAY       PROC FAR PUBLIC, 
               CBSEGADR:DWORD                ;Control block segment address 
               PUSH           DS 
               PUSHW          DSEG 
               POP            DS 
               XOR            EAX,EAX        ;Clear high words 
               XOR            EDX,EDX 
               MOV            AX,WORD PTR CBSEGADR[2] 
               MOV            DX,WORD PTR CBSEGADR[0] 
               SHL            EAX,4          ;Calculate linear address 
               ADD            EAX,EDX 
               MOV            CCODEPTR,EAX   ;Reset condition code address 
               POP            DS             ;Pop calling DS 
               PUSHD          OFFSET SUMARRAY32 
               CALL           ENTERPM        ;Execute SUMARRAY32 in protected 
               RET 
SUMARRAY       ENDP 
 
CSEG           ENDS 
 
TSEG           SEGMENT PARA PUBLIC USE32 'CODE' 
               ASSUME CS:TSEG, SS:TSEG, DS:TSEG, ES:TSEG, FS:DSEG, GS:DGROUP 
 
;Sum the elements of a single precision array.  Array parameters are stored 
;in a control block having structure of ARRAYDATA.  The linear address of the 
;control block is stored at CCODEPTR.  An error code of -1 is returned in the 
;condition code of the control block if the number of array elements is zero 
;XLIB places an error code in the control block if an FPU exception occurs 
;while calculating the sum.  This error code will have the FPU status word in 
;the high word and the XLIB FPU error code in the low word.  Observe that this 
;routine will be called with DS = FLATDSEL (flat-model data descriptor) and 
;FS = DSEGSEL (DSEG data descriptor). 
SUMARRAY32     PROC NEAR 
               MOV            EBX,FS:CCODEPTR               ;Get control block 
               MOV            EDX,ARRAYDATA.ADDRESS[EBX]    ;Get array address 
               MOV            ESI,ARRAYDATA.N[EBX]          ;Get N 
               SUB            ESI,1 
               JB             NODATA                        ;Error:  N = 0 
               FLDZ                                         ;Initialize sum 
SUMLOOP:       FADD           DWORD PTR [EDX+4*ESI] 
               SUB            ESI,1 
               JAE            SUMLOOP 
               FSTP           ARRAYDATA.SUM[EBX]            ;Save sum 
               RET 
NODATA:        MOV            ARRAYDATA.CONDCODE[EBX],-1    ;Record error code 
               RET 
SUMARRAY32     ENDP 
 
TSEG           ENDS 
               END