exarray.asm
资源名称:DOS系统的源代码.rar [点击查看]
上传用户:xiaoan1112
上传日期:2013-04-11
资源大小:19621k
文件大小:12k
源码类别:
操作系统开发
开发平台:
Visual C++
- page 49,132
- TITLE exarray - Array statement executors
- ;***
- ;exarray.asm - interpreter specific array support.
- ;
- ; Copyright <C> 1986, Microsoft Corporation
- ;
- ;Purpose:
- ;
- ; This module includes:
- ; - DIM, REDIM, and OPTION BASE executors.
- ;
- ;
- ;****************************************************************************
- .xlist
- include version.inc
- EXARRAY_ASM = ON
- IncludeOnce architec
- IncludeOnce context
- IncludeOnce executor
- IncludeOnce exint
- IncludeOnce extort
- IncludeOnce opid
- IncludeOnce opintrsc
- IncludeOnce opstmt
- IncludeOnce pcode
- IncludeOnce scanner
- IncludeOnce ui
- IncludeOnce variable
- .list
- assumes cs, CODE
- assumes es, NOTHING
- assumes ss, DATA
- extrn ScanExExit:far
- extrn B$ERAS:far
- extrn B$ADIM:far
- sBegin DATA
- extrn SsScanExSrc:word
- public DimAtScanType
- DimAtScanType db SSDIM_EXECUTE ; Type of Dim initiated by scanner
- sEnd DATA
- sBegin CODE
- ;***
- ;exStOptionBase<0|1>
- ;Purpose:
- ; Handled at scan time so it doesn't need to be executed
- ;
- ;***************************************************************************
- MakeExe exStOptionBase0,opStOptionBase0
- SkipExHeader
- MakeExe exStOptionBase1,opStOptionBase1
- jmp short Disp1
- ;***
- ;exDimOptionBase - executor to push current option base
- ;Purpose:
- ; Emit the current OPTION BASE setting.
- ; One use for this executor is as follows:
- ; Array dimension clauses in DIM and REMDIM may or may not use the
- ; TO keyword. This executor is used in cases where TO is not used
- ; so that DIM and REDIM executors always get both the lower and upper
- ; bound for each dimension.
- ;Input:
- ; none
- ;Output:
- ; stack contains current OPTION BASE (ET_I2).
- ;Modifies:
- ; none
- ;***************************************************************************
- MakeExe exDimOptionBase,opDimOptionBase
- GETRS_SEG es,bx,<SIZE,LOAD>
- mov bx,[grs.GRS_oMrsCur]
- RS_BASE add,bx
- xor ax,ax
- test BPTRRS[bx.MRS_flags],FM_OptionBase1
- je OptBase0 ;brif Current OPTION BASE setting is 0
- inc ax ;else it is 1
- OptBase0:
- push ax ;Return result on stack
- Disp1:
- jmp DispMov ; refresh es and dispatch
- subttl Value Table Reference Ids
- page
- ;***
- ;exAVtRf - variable table reference executor
- ;
- ;Purpose:
- ;
- ; This executor is used in the Dim, COMMON, SHARED, STATIC, Auto,
- ; and Public statements. The only executable statement in the
- ; group is Dim and this is only executable with FV_QB4LANG.
- ;
- ; There are two possible situations for these executors to be
- ; executed. The first is during scan time, these can be dispatched
- ; to allocate the storage for the array. Currently, this occurs for
- ; $Static Common arrays only and then during the Dim statement processing.
- ; The second situation is during normal execution with FV_QB4LANG. In this
- ; case, the array is checked if $Static or $Dynamic. If $Static, no
- ; action is taken if already allocated. If $Dynamic, allocation occurs.
- ;
- ;Input:
- ;Output:
- ;Modifies:
- ;***************************************************************************
- MakeExe exAVtRfSD,opAVtRf,ET_SD
- SkipExHeader
- MakeExe exAVtRfR8,opAVtRf,ET_R8
- SkipExHeader
- MakeExe exAVtRfI4,opAVtRf,ET_I4
- SkipExHeader
- MakeExe exAVtRfR4,opAVtRf,ET_R4
- SkipExHeader
- MakeExe exAVtRfI2,opAVtRf,ET_I2
- SkipExHeader
- MakeExe exAVtRfImp,opAVtRf,ET_Imp
- inc si ; Ignore argument count
- inc si
- LODSWTX
- xchg ax,bx ;BX = oVar
- DoDim:
- xor cx,cx ;Indicate Dim
- jmp short DimReDim ;Jump into shared code
- public DimImplicit
- DimImplicit:
- GETRS_SEG es
- mov bx,[grs.GRS_oMrsCur]
- RS_BASE add,bx
- mov al,BPTRRS[bx.MRS_flags] ;Low bound is option base
- .erre FM_OptionBase1 EQ 1
- and ax,FM_OptionBase1 ;AX = option base (0 or 1)
- mov dx,10 ;Upper bound is 10
- call GetEsDi ;Setup to access pcode
- mov cx,PTRTX[si] ;CX = cDims
- mov bx,PTRTX[si+2] ;BX = oVar
- @@:
- push ax ;Push low bound
- push dx ;Push upper bound
- loop @B ;Brif more dimensions
- mov [DimAtScanType],SSDIM_STATIC
- jmp short DoDim
- page
- ;***
- ;exStReDimTo - REDIM executors.
- ;
- ;Purpose:
- ;
- ; For DIM:
- ; =======
- ; Syntax: DIM <id>(x TO y,...) or DIM <id>(x,...)
- ; Runtime Entry Point for DIM for arrays.
- ; DIM Statement for dynamic arrays. If the array is
- ; already defined, an error is returned.
- ;
- ; For REDIM:
- ; =========
- ; Syntax: REDIM <id>(x TO y,...) or REDIM <id>(x,...)
- ; Runtime Entry Point for REDIM for arrays.
- ; This algorithm depends on:
- ; 1. VarMgr setting up an array template, even for dynamic or common
- ; variables.
- ; 2. Scanner verifying correctness of index argument count
- ;
- ;Input:
- ;
- ; Stack contains:
- ; Variable Table Offset
- ; Index count
- ; count index arguments, consisting of lower and upper bounds
- ;
- ;Output:
- ;
- ; none
- ;
- ;Modifies:
- ;
- ;*************************************************************************
- MakeExe exStReDimTo,opStReDimTo
- pop cx ; cx = pAD. This is never 0!!!
- DbAssertRel cx,ne,0,CODE,<exStReDimTo: pAD == 0>
- mov bx,PTRTX[si-4] ; Get Offset to Variable table
- DimReDim:
- DbChk oVar,bx ;Verify that this is a variable
- mov dx,[pVarBx-VAR_value].VAR_flags
- mov ax,dx
- and ax,FV_TYP_MASK
- jz RecArray
- .erre ET_MAX LT 100h ; Assure we can use AL
- cmp al,ET_FS ;[9]
- jb HavOTyp
- .erre ET_FS EQ ET_MaxStr ;[9]
- if ET_MaxStr NE ET_MAX
- ja HavOTyp
- endif ; ET_MaxStr NE ET_MAX
- push ax ; Save oTyp
- push [pVarBx-VAR_Value].VAR_cbFixed ; Push length
- jmp short HaveSize
- RecArray:
- mov ax,[pVarBx-VAR_value].VAR_oTyp ; Get type while we have pVt
- HavOTyp:
- push ax ; Save oTyp
- call OTypCbTyp ;ax = bytes in oType passed in ax
- push ax ;push cbElement
- HaveSize:
- ;Look for $STATIC array in COMMON
- cmp [DimAtScanType],SSDIM_COMMON
- jne NotStaticCommon ; Brif not Dim'ing $Static common
- pop cx ; cbElement
- pop ax ; oTyp
- push cx ; Restore cbElement
- mov dl,[pVarBx].ACOM_cDims
- mov dh,FADF_STATIC+FADF_NEAR
- cmp ax,ET_SD ;See if string
- jne @F
- or dh,FADF_SD ;Tell runtime this is a string array
- @@:
- push dx ;Push flags/cDims
- push [SsScanExSrc] ;Push pAd
- ;Compute size of $Static array and set up array descriptor
- call B$ADIM ;Compute array size, don't allocate
- mov [SsScanExSrc],ax ;Save return value
- jmp short DimXds ;Return to scanner
- NotStaticCommon:
- jcxz @F ; Brif Dim
- mov bx,cx ; DI:BX = sbAd:oAd
- mov cx,1 ; Needed below
- jmp short GotPAd
- @@:
- call oVarToPAd ;on exit bx = pAd
- ; sets FADF_STATIC & cDims in array desc
- GotPAd:
- ;It's OK to execute a single $STATIC DIM more than once. Multiple DIMs
- ;are caught at scan time. However, DIM of a $STATIC array passed as a
- ;parameter is illegal. In EB this test is not necessary because Dim
- ;statements are not executable. Therefore, a $Static array will
- ;never be allocated more than once.
- TestX dx,FVFORMAL ;Passed as parameter?
- pop dx ; cbElement
- pop ax ;AX = oTyp
- push dx ; Restore cbElement
- mov dx,word ptr [bx].AD_cDims ;get flags byte & cDimensions (set up
- ; by oVarToPAd)
- jnz @F ;Brif parameter, always attempt Dim
- ;Allow multiple DIM of $STATIC arrays
- test dh,FADF_STATIC ;$STATIC array?
- jz @F ;If not, always DIM it
- cmp [bx].FHD_hData,0 ;Space allocated to $STATIC array?
- jnz CleanUp ;If so, don't DIM again, no error
- @@:
- ;ax = oTyp
- ;ds:bx = pAD
- ;cx = 0 for DIM, 1 for REDIM
- ;dh = Feature flags
- ;dl = cDims
- ;Stack has cbElement followed by bounds
- cmp ax,ET_SD
- je SetSD
- or dh,FADF_FAR ;Assume array is far not huge
- test dh,FADF_STATIC ;$STATIC array?
- jnz @F ;They can never be huge
- test [cmdSwitches],CMD_SW_HAR
- jz @F ;Brif /AH switch not specified
- or dh,FADF_HUGE ;Set Huge indicator for runtime
- @@:
- Flags_Set:
- push dx ;flags/cDims
- push bx ;pAD
- SizeSet:
- jcxz Dim_The_Array ;Brif Dim
- CALLRT B$RDIM,Mov ;ReDim array via runtime code
- jmp short After_Dim
- SetSD:
- or dh,FADF_SD OR FADF_NEAR ;Tell runtime this is a string array
- jmp short Flags_Set
- CleanUp:
- mov dh,0 ;dx=cDims
- shl dx,1 ;Two words/dimension
- inc dx ; Plus one word for cbElement
- shl dx,1 ;Two bytes/index
- add sp,dx ;Clear indices off stack
- jmp short DimX
- Dim_The_Array:
- CALLRT B$DDIM,Mov ;Dimension array via runtime code
- After_Dim:
- DimXds:
- ;Determine how to return.
- mov al,SSDIM_EXECUTE
- xchg al,[DimAtScanType] ;Get Dim type and reset
- cmp al,SSDIM_EXECUTE ;Is this execute scan time Dim?
- jne DimAtScanExit ;Brif not
- ;Exit for case that DIM executed as part of normal pcode execution
- DimX:
- DispMac
- ;Exit for a Dim that was executed at scan time for a $Static array
- DimAtScanExit:
- jmp ScanExExit ; Exit
- subttl exStErase
- page
- ;***
- ;exStErase - erase one or more arrays
- ;
- ;Purpose:
- ;
- ; Support for ERASE statement.
- ;
- ;Input:
- ;
- ; es:si = pcode address of argument count
- ; count pAD arguments on the stack
- ;
- ;Output:
- ;
- ; none
- ;
- ;************************************************************************
- MakeExe exStErase,opStErase
- LODSWTX ;Load argument count
- mov di,ax ;Arg count to di
- EraseNext:
- call B$ERAS ;erase this array descriptor
- ;Note: this CAN cause heap movement
- dec di
- jnz EraseNext ;Go erase next array
- jmp DispMov
- subttl UnlinkArray
- page
- ;***
- ;UnlinkArray
- ;
- ;Purpose:
- ;
- ; This routine unlinks Auto non-string arrays from the owners frame
- ;
- ;Input:
- ;
- ; sbAd:pAd on stack
- ;
- ;Output:
- ;
- ; none
- ;
- ;Preserves:
- ;
- ; DI
- ;
- ;************************************************************************
- ;***
- ;exFn<U|L>bound<1|2>
- ;
- ;Purpose:
- ;
- ; Support for LBOUND function
- ;
- ;Input:
- ;
- ; pAD on the stack
- ; iDim on stack (exFnLbound2 only)
- ;
- ;Output:
- ;
- ; none
- ;
- ;************************************************************************
- ;
- MakeExe ExFnLbound1,opFnLbound1
- PushI ax,1
- SkipExHeader
- MakeExe ExFnLbound2,opFnLbound2
- CALLRT B$LBND,DispAx
- MakeExe ExFnUbound1,opFnUbound1
- PushI ax,1
- SkipExHeader
- MakeExe ExFnUbound2,opFnUbound2
- CALLRT B$UBND,DispAx
- ;=============================================================================
- subttl Utilities
- page
- ;***
- ;OTypCbTyp
- ;Purpose:
- ; This routine returns the number of bytes of data required for
- ; the input type.
- ; Significantly rewritten for revision [7].
- ;
- ;Input:
- ; ax = oTyp
- ;Output:
- ; ax = cbTyp
- ;Modifies:
- ; none
- ;Preserves:
- ; all
- ;***************************************************************************
- mpCbTyp equ $-1
- .erre ET_I2 EQ ($-mpCbTyp)
- DB 2 ;ET_I2
- .erre ET_I4 EQ ($-mpCbTyp)
- DB 4 ;ET_I4
- .erre ET_R4 EQ ($-mpCbTyp)
- DB 4 ;ET_R4
- .erre ET_R8 EQ ($-mpCbTyp)
- DB 8 ;ET_R8
- .erre ET_SD EQ ($-mpCbTyp)
- db SIZE SD
- OTypCbTyp:
- push bx
- DbChk oTyp,ax ;sanity check on input oTyp
- cmp ax,ET_MAX ;Is it a fundamental type?
- ja NotPredefinedType ; brif not - user defined
- DbAssertRel ax,be,ET_SD,CODE,<OTypCbTyp: Invalid oTyp>
- mov bx,offset cs:mpCbTyp ;base of lookup table in CS
- xlat byte ptr cs:[bx] ;al == desired size
- OTypCbTyp_Exit:
- pop bx
- ret
- NotPredefinedType:
- push cx
- push dx
- push es
- cCall CbTypFar,<ax>
- pop es
- pop dx
- pop cx
- jmp OTypCbTyp_Exit
- sEnd CODE
- end