📄 strnum.asm
字号:
TITLE STRNUM - String to number and number to string conversions
;***
; STRNUM - String to number and number to string conversions
;
; Copyright <C> 1986, Microsoft Corporation
;
;Purpose:
;
; BASIC Syntax mapping to included runtime entry points:
;
;
; CVI Function: CVL Function:
;
; v = CVI(2-byte string) v = CVL(4-byte string)
; | |
; B$FCVI B$FCVL
;
;
; CVS Function: CVD Function:
;
; v = CVS(4-byte string) v = CVD(8-byte string)
; | |
; B$FCVS B$FCVD
;
;
; CVSMBF Function: CVDMBF Function:
;
; v = CVSMBF(4-byte string) v = CVDMBF(8-byte string)
; | |
; B$FCSF B$FCDF
;
;
; MKI$ Function: MKL$ Function:
;
; v$ = MKI$(integer exp) v$ = MKL$(long integer exp)
; | |
; B$FMKI B$FMKL
;
;
; MKS$ Function: MKD$ Function:
;
; v$ = MKS$(s.p. exp) v$ = MKD$(d.p. exp)
; | |
; B$FMKS B$FMKD
;
;
; MKSMBF$ Function: MKDMBF$ Function:
;
; v$ = MKSMBF$(s.p. exp) v$ = MKDMBF$(d.p. exp)
; | |
; B$FMSF B$FMDF
;
;******************************************************************************
INCLUDE switch.inc
INCLUDE rmacros.inc ; Runtime Macro Defintions
useSeg ST_TEXT
useSeg _TEXT
useSeg _DATA
useSeg _BSS
INCLUDE seg.inc
INCLUDE baslibma.inc
INCLUDE string.inc
sBegin _DATA
externW B$AC
externW B$DAC
sEnd _DATA
sBegin _BSS
externB b$Buf3 ; temporary space
sEnd _BSS
externFP B$ERR_OV ; FAR because it's JMP'ed to from _TEXT
sBegin _TEXT
externNP $i4_m4
externNP $i8_m8
externNP $m4_i4
externNP $m8_i8
sEnd _TEXT
sBegin ST_TEXT
externNP B$STDALCTMP
externNP B$STALCTMPCPY
externNP B$STALCTMP
externNP B$ERR_FC
ASSUMES CS,ST_TEXT
SUBTTL
PAGE
;***
;STRCPY - copy CX bytes from string to given location & free string if temp.
;
;Purpose:
; This routine is shared code for the CVS/CVD/... routines. Must be far, since
; it is called from another segment in some routines defined below.
;
;Entry:
; [BX] = pointer to a string descriptor.
; [CX] = count of bytes to copy from the string
; [DI] = target address for the copy.
;
;Exit:
; The copy is made, and the string is deallocated it temp.
; [AX] = pointer to the start of the target address (input DI)
;
;Modifies:
; Per Convention
;
;******************************************************************************
cProc STRCPY,FAR,<DI,SI,ES> ; added this routine to save code
cBegin
CMP BYTE PTR[BX],CL ;See if string is long enough
JB ARGERR
PUSH DS
POP ES ;[ES] = [DS]
MOV SI,[BX+2] ;Get address of data area
PUSH DI ;save for retval
REP MOVSB ;copy the string data
CALL B$STDALCTMP ;Delete string if temp
POP AX ;pointer to target address
cEnd
ARGERR: JMP B$ERR_FC ;Illegal function call
;***
; B$FCVI - Convert string to integer
;
;Function:
; Make sure string is at least 2 bytes long, then return the first 2 bytes
; as an integer.
;
;Inputs:
; sdNum = string descriptor
;
;Outputs:
; [AX] = number
;
;Registers:
; Per convention
;
;******************************************************************************
cProc B$FCVI,<FAR,PUBLIC>
cBegin <nogen>
MOV CL,2 ;[CL] = length to do
SKIP 2 ; fall through - share code
cEnd nogen
;***
; B$FCVL - Convert string to long integer
;
;Function:
; Make sure string is at least 4 bytes long, then return the first 4 bytes
; as a long integer.
;
;Inputs:
; sdNum = string descriptor
;
;Outputs:
; [DX:AX] = number
;
;Registers:
; Per convention
;
;******************************************************************************
cProc B$FCVL,<FAR,PUBLIC>
cBegin <nogen>
MOV CL,4 ;[CL] = length to be copied
XOR CH,CH
cEnd <nogen> ; fall through to common code
cProc BFCV_Int,<FAR>,DI
parmSD sdNum
cBegin
GetpSD BX,sdNum ; [BX] = psdNum
MOV DI,OFFSET DGROUP:B$AC ;[DI] = pointer to dummy place to copy
CALL STRCPY
XCHG AX,BX ;[BX] = pointer to number
MOV AX,[BX] ;[AX] = low word of number (both CVL and CVS)
MOV DX,[BX+2] ;[DX] = high word (CVL only, else garbage)
cEnd
;***
; B$FCVS, B$FCVD - Convert string to single or double precision number
;
;Function:
; Convert the string to single or double precision number. Make sure it's long
; enough first.
;
;Inputs:
; sdNum = string descriptor
;
;Outputs:
; [AX] = pointer to resulting number in FAC/DAC
;
;Registers:
; per convention
;******************************************************************************
cProc B$FCVS,<FAR,PUBLIC>
cBegin <nogen>
MOV CL,4
SKIP 2
cEnd <nogen> ; fall through to share code
cProc B$FCVD,<FAR,PUBLIC>
cBegin <nogen>
MOV CL,8
XOR CH,CH
cEnd <nogen>
cProc BFCV_Real,<FAR>,DI
parmSD sdNum
cBegin
MOV DI,OFFSET DGROUP:B$DAC
GetpSD BX,sdNum ; [BX] = psdNum
CALL STRCPY
cEnd
;***
; B$FMKI, B$FMKL, B$FMKS, B$FMKD - Convert number to string
;
;Function:
; Create a 2-, 4-, or 8-byte temp string and put the number in it.
;
;Inputs:
; ivar = Integer to be converted (MKI)
; lvar = Long integer to be converted (MKL)
; R4var = real (s.p.) number to be converted (MKS)
; R8var = real (d.p.) number to be converted (MKD)
;
;Outputs:
; [AX] = Address of string descriptor
;
;Registers:
; Per convention
;
;******************************************************************************
cProc B$FMKI,<FAR,PUBLIC>
parmW ivar
cBegin
MOV BX,2 ;Create a string of length 2
LEA DX,ivar ; [DX] = pointer to input parm
CALL B$STALCTMPCPY ; Allocate string and copy data in
XCHG AX,BX ; [AX] = pointer to descriptor
cEnd
cProc B$FMKL,<FAR,PUBLIC>
cBegin <nogen>
cEnd <nogen> ; share code with B$FMKS
cProc B$FMKS,<FAR,PUBLIC>
parmD R4num
cBegin
MK_4:
MOV BX,4 ;Create a string of length 4
LEA DX,R4num ; [DX] = pointer to input parm
CALL B$STALCTMPCPY ; Allocate string and copy data in
XCHG AX,BX ; [AX] = pointer to descriptor
cEnd
cProc B$FMKD,<FAR,PUBLIC>
parmQ R8num
cBegin
MOV BX,8 ;4 Bytes in single precision number
LEA DX,R8num ;[DX] = pointer to data
CALL B$STALCTMPCPY ;Allocate string and copy data in
XCHG AX,BX ;[AX] = pointer to descriptor
cEnd
sEnd ST_TEXT
sBegin _TEXT
assumes CS,_TEXT
;***
;Ix_Mx
;
;Purpose:
; Since the low-level conversion functions (MBF to/from IEEE) are near routines
; in _TEXT, B$MCVS & B$MCVD call this routine to do the actual conversion
; (so they can be in ST_TEXT).
;
;Entry:
; AX is 4 if $i4_m4 is to called, 8 if $i8_m8 is to be called.
;
;******************************************************************************
;***
;Mx_Ix
;
;Purpose:
; Since the low-level conversion functions (MBF to/from IEEE) are near routines
; in _TEXT, B$FMSF & B$FMDF call this routine to do the actual conversion
; (so they can be in ST_TEXT).
;
;Entry:
; CX is 4 if $m4_i4 is to called, 8 if $m8_i8 is to be called.
;
;******************************************************************************
IX_MX_DISP:
DW _TEXTOFFSET $i4_m4
DW _TEXTOFFSET $i8_m8
MX_IX_DISP:
DW _TEXTOFFSET $m4_i4
DW _TEXTOFFSET $m8_i8
cProc Ix_Mx,<FAR>
cBegin <nogen>
MOV BX,_TEXTOFFSET IX_MX_DISP
JMP SHORT Convert_Common
cEnd <nogen>
cProc Mx_Ix,<FAR>
cBegin <nogen>
XCHG AX,CX ; put input into AX for common code, below
MOV BX,_TEXTOFFSET MX_IX_DISP
cEnd <nogen>
cProc Convert_Common,<FAR>
cBegin
SHR AL,1 ; convert AL = 4 or 8 to AL = 0 or 2
SHR AL,1
AND AL,0FEH
ADD BL,AL ; add offset to dispatch table start
CALL CS:[BX] ; call appropriate mathpack routine
OR AX,AX ; Overflow?
JZ Convert_done ; Jump if not
JMP B$ERR_OV ; Else declare error
Convert_done:
cEnd
sEnd _TEXT
sBegin ST_TEXT
assumes CS,ST_TEXT
;***
;B$MCVS - CVSMBF function
;
;Purpose:
; Given a string containing a 4-byte s.p. number in Microsoft Binary Format,
; return a pointer to an s.p. number in IEEE format.
;
;Entry:
; sdNum - string descriptor for the 4-byte string
;
;Exit:
; [AX] = pointer to resulting number in FAC.
;
;Uses:
; Per convention
;******************************************************************************
cProc B$MCVS,<PUBLIC,FAR,NODATA>
cBegin <nogen>
MOV CL,4
SKIP 2
cEnd <nogen>
;***
;B$MCVD - CVDMBF function
;
;Purpose:
; Given a string containing a 8-byte d.p. number in Microsoft Binary Format,
; return a pointer to an d.p. number in IEEE format.
;
;Entry:
; sdNum - string descriptor for the 4-byte string
;
;Exit:
; [AX] = pointer to result in DAC
;
;Uses:
; Per convention
;******************************************************************************
cProc B$MCVD,<PUBLIC,FAR,NODATA>
cBegin <nogen>
MOV CL,8
XOR CH,CH
cEnd <nogen>
cProc BMCV_Real,<FAR,NODATA>,<ES,SI,DI>
parmSD sdNum
cBegin
MOV SI,OFFSET DGROUP:B$DAC
GetpSD BX,sdNum ;BX = psdNum
MOV DI,OFFSET DGROUP:b$Buf3 ; temporary storage (>= 8 bytes)
PUSH CX ;Save the byte count
CALL STRCPY ;copy data to $FTMP, delete string if temp
POP AX ;[AX] = count of bytes
XCHG SI,DI ;SI points to B$FTMP1 (input number)
PUSH DS
POP ES ;ES = DS for math format mapping call
PUSH DI ;save pointer to result for retval
CALL Ix_Mx ; perform actual conversion
POP AX ;restore pointer to converted number in DAC
cEnd
;***
;B$FMDF - MKDMBF$ function
;
;Purpose:
; Given an 8-byte d.p. number in IEEE format, return a pointer to
; an sd containing the d.p. number in Microsoft Binary Format.
;
;Entry:
; R8parm - a d.p. number
;
;Exit:
; [AX] = pointer to a string descriptor
;
;Uses:
; Per convention
;******************************************************************************
cProc B$FMDF,<PUBLIC,FAR,NODATA> ;[6][3]
parmQ R8parm
cBegin
MOV BX,8 ; 8 Bytes in d.p. # (required string size)
LEA AX,R8parm
CALL MK_MBF_SHARED
cEnd
;***
;B$FMSF - MKSMBF$ function
;
;Purpose:
; Given a 4-byte s.p. number in IEEE format, return a pointer to
; an sd containing the s.p. number in Microsoft Binary Format.
;
;Entry:
; R4parm - a s.p. number
;
;Exit:
; [AX] = pointer to a string descriptor
;
;Uses:
; Per convention
;******************************************************************************
cProc B$FMSF,<PUBLIC,FAR,NODATA> ;[6][3]
parmD R4parm
cBegin
MOV BX,4 ; 4 Bytes in s.p. # (required string size)
LEA AX,R4parm
CALL MK_MBF_SHARED
cEnd
cProc MK_MBF_SHARED,<NEAR>,<ES,SI,DI> ;[6]
cBegin
XCHG AX,SI ; DS:SI = source address
PUSH BX ; save size of number
CALL B$STALCTMP ;allocate temp string; DX points to data area
MOV DI,DX ;DI = target address
PUSH DS
POP ES ;ES:DI = target address
POP CX ; restore size of number
PUSH BX ;save address of string descriptor (for retval)
CALL Mx_Ix ; do the actual conversion
POP AX ;restore pointer to string descriptor
cEnd
sEnd ST_TEXT
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -