home *** CD-ROM | disk | FTP | other *** search
- PAGE ,105
- TITLE Substitute VAL Functions
- .MODEL MEDIUM
- ;********************************************************************
- ; VALSUB.ASM *
- ; Two assembled functions for compiled BASIC 7 programs to avoid *
- ; linking in the floating-point emulator code with VAL. Both return *
- ; the numeric equivalent of a string of decimal digits. *
- ; ATOI(<string>) [DECLARE FUNCTION ATOI% (A$)] returns the value *
- ; as an integer. ATOL(<string>) [DECLARE FUNCTION ATOL& (A$)] *
- ; returns the value as a long. *
- ; Both functions will delete leading spaces and will recognize a *
- ; leading minus sign. Neither function recognizes hex or octal *
- ; input. WARNING: Neither function is checked for overflow. *
- ;-------------------------------------------------------------------*
- ; Written by M. L. Lesser, January 20, 1991 *
- ; Assembled with Microsoft MASM v 5.1 *
- ;********************************************************************
-
- EXTRN StringAddress: FAR ;BC 7 link-library "mixed
- EXTRN StringLength: FAR ; language" functioons
-
- .CODE
- PUBLIC ATOI, ATOL
- ATOI PROC ;The two procedures are identical -
- ATOL PROC ; the DECLARE statement sets return
- PUSH BP
- MOV BP,SP
- PUSH SI
- PUSH DI
- PUSH DS
- XOR AX,AX ;Initialize MINUS flag (on stack)
- PUSH AX
- ; Find the string-space representation of the input string:
- PUSH 6[BP] ;Get length
- CALL StringLength ;Returns length in AX
- OR AX,AX
- JZ NULL ;Fix-up (at end) for null input string
- PUSH AX ;Save length for later
- PUSH 6[BP] ;Get address of input string
- CALL StringAddress ;Returns far address in DX:AX
- POP CX ;CX now has length of string
- MOV DS,DX ;Set DS:DI to start of string
- MOV SI,AX
- XOR AX,AX ;Clear critical registers
- MOV DX,AX
- MOV BX,AX
- DEBLANK: ;Delete any leading <SP> symbols
- LODSB
- CMP AL,' '
- JNZ NEGIT
- LOOP DEBLANK
- JCXZ NULL ;If string has all <SP> characters!
- NEGIT: CMP AL, '-' ;Check for negative
- JNZ HERE ;If not, check for valid digit
- POP BX ;Else set MINUS flag
- PUSH AX
- DEC CX
- ; Evaluate digits in string, from left to right. Value will be
- ; accumulated in DX:BX, multiplying old value by ten before each
- ; new digit is added in. Quit at first non-digit byte.
- ADDEM: LODSB
- HERE: CMP AL,'9' ;Check if we are still within range
- JA NOMORE
- CMP AL,'0'
- JB NOMORE
- AND AL,0FH ;Make into hex digit
- SHL BX,1 ;Multiply DX:BX by two
- RCL DX,1
- MOV BP,BX ;Save twice value in DI:BP
- MOV DI,DX
- SHL BX,1 ;Now multiplied by four
- RCL DX,1
- SHL BX,1 ;By eight
- RCL DX,1
- ADD BX,BP ;By ten
- ADC DX,DI
- ADD BX,AX ;Plus new digit
- ADC DX,0
- LOOP ADDEM
- NOMORE: MOV AX,BX ;Positive value now in DX:AX
- ; Change sign of value if MINUS set:
- POP BX
- OR BX,BX
- JZ DONE ;If not we are done
- NEG DX ;Else negate DX:AX
- NEG AX
- SBB DX,0
- DONE: POP DS
- POP DI
- POP SI
- POP BP
- RET 2
- NULL: POP AX ;Fix up for no digits
- MOV DX,AX
- JMP DONE
- ATOL ENDP
- ATOI ENDP
- END