📄 util.asm
字号:
TITLE util.asm - general purpose utilities (not provided by runtime)
;***
;util.asm - general purpose utilities for the interpreter
;
; Copyright <C> 1986, Microsoft Corporation
;
;Purpose:
; Any general purpose (i.e., code that is deemed to be not tied to
; any single function area) utility routine in the interpreter
; will be placed here. In some cases, speed-critical routines may
; be present which duplicate runtime code, but for which we don't
; want to pay the size and speed penalty of a long call, and/or we
; don't want to pay for the C calling convention.
;
;
;****************************************************************************
.xlist
UTIL_ASM = 1 ;We need to do this before including version.inc
;since version.inc ultimately includes
;debug.inc, which depends on UTIL_ASM
include version.inc
includeOnce heap
includeOnce context
.list
sBegin DATA
sEnd DATA
sBegin RT
EXTRN B$SCAT:FAR
EXTRN B$FLEN:FAR
EXTRN B$END:FAR
sEnd RT
; .sall
assumes CS,CP
assumes DS,DATA
assumes ES,DATA
assumes SS,DATA
page
sBegin CP
subttl Zero fill routine.
page
;***
;ZeroFill(pDst, cbFill) - Zero fills a block of size cbFill, starting at pDst
;
;Entry: two values on the stack (C calling convention):
; - a pointer to the string.
; - the number of bytes to fill.
; NOTE: This routine shares code with FillUndef; the interface to these
; two routines must match, as they share a common exit.
;
;Exit:
; On exit, [ax] == 0
;Uses:
; none.
;****
cProc ZeroFill,<PUBLIC,FAR>,<DI>
parmW pDst
parmW cbFill
cBegin
xor ax,ax
mov cx,cbFill
FillBytes: ;start of shared code with FillUndef (below)
jcxz ZeroEnd
push ds ;require ES = DS for rep movs
pop es
cld
mov di,pDst
shr cx,1 ;convert to a word count
repz stosw
jnc ZeroEnd ;no carry if byte count was even
stosb ;move the last (odd) byte
DbChk Heaps ;check in case we hosed the heap
ZeroEnd:
cEnd
subttl Routine to fill a block of words with UNDEFINED
page
;***
;FillUndef(pDst, cwFill) - fills cwFill words w/UNDEFINED, starting at pDst
;
;Entry: two values on the stack (C calling convention):
; - a pointer to the start of the block to fill.
; - the number of words to fill.
; NOTE: This routine shares code with ZeroFill; the interface to these
; two routines must match, as they share a common exit.
;
;Exit:
; On exit, [ax] == UNDEFINED
;Uses:
; none.
;****
cProc FillUndef,<PUBLIC,FAR>,<DI>
parmW pDst
parmW cwFill
cBegin
mov cx,cwFill
shl cx,1 ;convert word count to byte count for fill
mov ax,UNDEFINED ;NOTE: assuming here that low byte and high
; byte of UNDEFINED are the same
jmp short FillBytes ;share code with ZeroFill, above
cEnd nogen
;***
;VOID CopyBlk(pbSrc, pbDst, cb) - do a simple block copy within DGROUP
;
;Purpose:
; Copy a block of bytes. This function should not be used
; if the source block intersects with the destination block,
; and begins at a lower address than the destination block,
; otherwise, it will overwrite part of the destination before
; it gets to it. Use function CopyBlkHighLow (as yet unwritten)
; for this case.
;Entry:
; 3 values on the stack (C calling convention):
; - a pointer to the lowest addressed source byte,
; - a pointer to the lowest addressed destination byte,
; - the number of bytes to copy.
;Exit:
; none
;
;****
cProc CopyBlk,<PUBLIC,FAR>,<si,di>
parmW pbSrc
parmW pbDst
parmW cb
cBegin
mov si,pbSrc ;si = source offset
mov di,pbDst ;di = destination offset
mov cx,cb
push ds ;movsb requires es = ds
pop es
rep movsb ;copy block
DbChk Heaps ;check in case we hosed the heap
cEnd
;********************************************************************
; short CmpPsdIns(psd1, psd2, cbMax)
; Purpose:
; Perform a CASE insensitive comparison of two strings
;
; Entry:
; parm1: ax = psd1 - points to 1st string descriptor
; parm2: bx = psd2 - points to 2nd string descriptor
; parm3: dx = cbMax cmp - max. number of chars to use in comparison
;
; Exit:
; If strings are the same, returns ax=0
; If psd1 <> psd2, return ax not 0
; (it is much faster for this function to not differentiate
; between psd1 < psd2 or psd1 > psd2, and callers just care
; about equality AND SPEED)
; Also sets PSW flags via or ax,ax just prior to exit.
;
;********************************************************************
cProc CmpPsdIns,<PUBLIC,NEAR>,<si>
cBegin
xchg ax,si ;si -> sd 1
lodsw ;ax = byte count for string 1
mov cx,ax ;cx = byte count for string 1
cmp dx,cx
jae Got_Cb1 ;brif count is <= max cout to be used
mov cx,dx
Got_Cb1:
lodsw ;ax -> string 1
mov si,bx ;si -> sd 2
mov bx,ax ;bx -> string 1
lodsw ;ax = byte count for string 2
cmp dx,ax
jae Got_Cb2
xchg ax,dx
Got_Cb2:
cmp ax,cx
mov ax,UNDEFINED ;prepare for Not-Equal return
jne CmpPsdExit ;brif strings are of different lengths
lodsw ;ax -> string 2
xchg ax,si ;si -> string 2
;At this point,
; bx points to 1st byte of string 1,
; si points to 1st byte of string 2
; cx = # bytes to compare
call CmpStrIns ;compare strings, ax=0 if equal
CmpPsdExit: ;return ax
or ax,ax ;set flags
cEnd
;********************************************************************
; CmpStrIns
; Purpose:
; Compare 2 strings, ignoreing case sensitivity
;
; Entry:
; bx points to 1st byte of string 1,
; si points to 1st byte of string 2
; cx = # bytes to compare
;
; Exit:
; If strings are the same, returns ax=0
; If string1 < string2, return ax=FFFFh
; if string1 > string2, return ax=0001h
; Also sets PSW flags via or ax,ax just prior to exit.
;
;********************************************************************
cProc CmpStrIns,<PUBLIC,NEAR>,<si>
cBegin
mov dx,0DFDFH ; mask for converting lower->upper
CmpLoop:
lodsb ;al = next byte from string 2
mov ah,[bx] ;ah = next byte from string 1
inc bx
and ax,dx ;force al and ah to upper case
cmp al,ah
loope CmpLoop ;branch if equal so far, and cx<>0
mov ax,1
jb CmpStrExit ;branch if string1 > string2
je CmpStrEqual ;branch if string1 = string2
dec ax ;else string1 < string2
CmpStrEqual:
dec ax
CmpStrExit:
or ax,ax ;set PSW flags for callers
cEnd
;*********************************************************************
; MapCpW, MapEsW
; Purpose:
; Map a value from one table to another.
; If value not found in search table, word beyond end of
; map table is returned.
; Entry:
; ax = value to search for
; cx = number of values in search table
; dx = ptr to table of values to search for
; bx = ptr to cooresponding table of map (result) values
; Exit:
; ax = value from map table
;
; MapCpW Alters ES
;
;*********************************************************************
PUBLIC MapCpW
MapCpW PROC NEAR ;maps using CP segment
push cs
pop es ;es = code segment
MapCpW ENDP
;fall into MapEsW
PUBLIC MapEsW
MapEsW PROC NEAR
push di ;save caller's di
push cx ;save number of bytes in table
mov di,dx ;di -> 1st word in table to search
repne scasw ;search for value in table pointed
; to by di (uses es)
pop ax ;ax = number of bytes in table
sub ax,cx ;ax = offset into table
add bx,ax ;bx = pointer to result value
mov ax,es:[bx]
pop di ;restore caller's di
ret
MapEsW ENDP
;*************************************************************************
; ushort CbSz(sz)
;
; Purpose:
; Return the number of bytes in a 0-byte terminated string.
; Does not include terminator in count.
;
; Entry:
; parm1: char *sz - ptr to source string
;
; Exit:
; [AX] = byte count
;
;*************************************************************************
cProc CbSz,<PUBLIC,FAR>,<di>
parmW sz
cBegin
push ds
pop es ;es = DGROUP
mov di,sz ;di points to start of string
mov cx,0FFFFH ;ax = max byte count
sub ax,ax ;al = byte to search for
repne scasb ;while cx != 0 and es:[di] != al, di++
sub ax,cx
dec ax
dec ax ;ax = length of string (0..n)
cEnd
;*************************************************************
;RelTempSd_CP
;Purpose:
; release temp string descriptor
;Entry:
; stack parm points to temp string descriptor to be released
;
;*************************************************************
PUBLIC RelTempSd_CP
RelTempSd_CP PROC NEAR
pop bx ;bx = return adr
pop ax ;ax = parm
push bx ;push back return adr
push ax ;pass ptr to string desc
call B$FLEN ;release temp descriptor
; (side effect of LEN function)
ret
RelTempSd_CP ENDP
sEnd CP
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -