home *** CD-ROM | disk | FTP | other *** search
- COMMENT ~
- STRINGS.ASM -- String Manipulation Procedures
-
- From `BLUEBOOK of ASSEMBLY ROUTINES for the IBM PC & XT'
- by Christopher L. Morgan
- Copyright (C) 1984 by The Waite Group, Inc.
-
- Purpose: These routines manipulate strings.
-
- Contents:
- ---------
- COMPARE -- Compare two strings
- LEXINSERT -- Lexigraphically insert
- LEXSEARCH -- Search a lexigraphically ordered list
- LOWERCASE -- Convert to lower case
- SORTB -- Bubble sort a string array
- STRINSERT -- Insert one string in another
- STRSEARCH -- Search for one string within another
- SWITCH -- Switch two strings
- UPPERCASE -- Convert to upper case
- _____________________________________________________________________________
- ~
- DATAS SEGMENT PUBLIC
- DUMMY DB 5 DUP(?)
- DATAS ENDS
- ;_____________________________________________________________________________
- CODES SEGMENT
- PUBLIC LOWERCASE,UPPERCASE,STRSEARCH,STRINSERT
- PUBLIC LEXSEARCH,LEXINSERT,COMPARE,SWITCH,SORTB
- ASSUME CS:CODES,DS:DATAS
- ;____________________________I/O ROUTINES_____________________________________
- ;Routine to convert string to lower case
- LOWERCASE PROC FAR
- PUSH BX ;Save registers
- PUSH CX
- PUSH AX
- ;
- ;Get the length
- MOV CX,[BX] ;First two bytes contain length
- INC BX ;Point to beginning of text
- INC BX
- ;
- ;Loop through the bytes of the string
- LOWERCASE1:
- MOV AL,[BX] ;Get the character
- CMP AL,'A' ;Below the upper case chars?
- JB LOWERCASE2 ;If so, skip
- CMP AL,'Z' ;Above the upper case chars?
- JA LOWERCASE2 ;If so, skip
- OR AL,20H ;OR bit 5 into the byte
- LOWERCASE2:
- MOV [BX],AL ;Store the character
- INC BX ;Point to next character
- LOOP LOWERCASE1
- POP AX ;Restore registers
- POP CX
- POP BX
- RET
- LOWERCASE ENDP
- ;------------------------------------------------------------------------------
- ;Routine to convert string to uppercase
- ;
- UPPERCASE PROC FAR
- PUSH BX ;Save registers
- PUSH CX
- PUSH AX
- ;
- ;Get the length
- MOV CX,[BX] ;First two bytes contain length
- INC BX ;Point to beginning of text
- INC BX
- ;
- ;Loop through the bytes of the string
- UPPERCASE1:
- MOV AL,[BX] ;Get the character
- CMP AL,'a' ;Below the lower case chars?
- JB UPPERCASE2 ;If so, skip
- CMP AL,'z' ;Above the lower case chars?
- JA UPPERCASE2 ;If so, skip
- AND AL,5FH ;Mask out bit number 5
- UPPERCASE2:
- MOV [BX],AL ;Store the character
- INC BX ;Point to next character
- LOOP UPPERCASE1
- POP AX ;Restore registers
- POP CX
- POP BX
- RET
- UPPERCASE ENDP
- ;------------------------------------------------------------------------------
- ;Routine to search for one string within another
- ;
- STRSEARCH PROC FAR
- PUSH SI ;Save registers
- PUSH DI
- PUSH CX
- ;
- ;Get length of destination and point to first byte
- MOV SI,DX ;Use source index
- LODSW ;Get the length of destination
- MOV CX,AX ;Use the length as a count
- MOV DX,SI ;Text begins here
- STRSEARCH1:
- ;
- ;Point indices to beginning of source and destination
- MOV SI,BX ;Load source index
- MOV DI,DX ;Load destination index
- ;
- ;Scan for a match
- MOV AL,[SI+2] ;Get the first character
- CLD ;Point forward
- REPNZ SCASB ;Scan for match
- JCXZ STRSEARCH2 ;If no match, quit
- ;
- ;Got a match of first characters -- now check the entire string
- MOV DX,DI ;Save current dest location
- DEC DI ;Beginning of word
- LODSW ;Get source length
- XCHG CX,AX ;Use sourc cnt & save dest cnt
- REPZ CMPSB ;Compare two strings
- JCXZ STRSEARCH3 ;It`s a match if no more source
- ;
- ;Continue the scan
- XCHG CX,AX ;Use destination count
- JMP STRSEARCH1 ;Back for more scanning of dest
- ;
- ;No match is possible
- STRSEARCH2:
- MOV AL,0 ;Unsuccessful outcome
- JMP STRSEARCHXIT
- ;
- ;Found a match
- STRSEARCH3:
- DEC DX ;Point to beginning of match
- MOV AL,0FFH ;Successful outcome
- JMP STRSEARCHXIT
- STRSEARCHXIT:
- POP CX ;Restore registers
- POP DI
- POP SI
- RET
- STRSEARCH ENDP
- ;------------------------------------------------------------------------------
- ;Routine to insert one string within another
- ;
- STRINSERT PROC FAR
- PUSH SI ;Save registers
- PUSH DI
- PUSH CX
- PUSH AX
- ;
- ;Find current end of destination string
- MOV SI,BP ;Start of string
- ADD SI,ES:[SI] ;Point to next to last byte
- INC SI ;Adjust for length information
- ;
- ;Find new end of destination string and update length
- MOV DI,SI ;Get old end of destination
- MOV AX,[BX] ;Get length of source
- ADD DI,DX ;New end of destination
- ADD ES:[BP],AX ;New length of destination
- ;
- ;Move tail of destination string out of the way
- MOV CX,SI ;SI + DX + 1 is the count
- SUB CX,DX
- INC CX
- STD ;Backward direction
- REP MOVS BYTE PTR[DI],ES:[SI] ;Move the tail
- ;
- ;Move source string into place
- MOV DI,DX ;Destination of move
- MOV SI,BX ;Source of movw
- CLD ;Forward direction
- LODSW ;Length of source
- MOV CX,AX ;The count
- REP MOVSB ;Make the string move
- STRINSERTXIT:
- POP AX ;Restore registers
- POP CX
- POP DI
- POP SI
- RET
- STRINSERT ENDP
- ;------------------------------------------------------------------------------
- ;Routine to search for a word in an ordered list of words
- ;
- LEXSEARCH PROC FAR
- ;
- PUSH SI ;Save register
- PUSH DI
- PUSH CX
- ;
- ;Point to beginning of list and get its length
- MOV DI,BP ;Beginning of list
- MOV CX,[DI] ;Get length
- INC DI
- INC DI
- ;
- ;Compare source word with words in the list
- LEXSEARCH1:
- MOV DX,DI ;Save beginning of dest word
- CLD ;Forward direction
- MOV SI,BX ;Point to beginning of source
- INC SI
- INC SI
- ;
- ;Compare source word with a word of the list
- LEXSEARCH2:
- ;
- ;Check for end of the list
- JCXZ LEXSEARCH5 ;End of list -- insert it
- ;
- ;Set up <CR> as scan character
- MOV AL,13 ;ASCII <CR>
- ;
- ;Check for end of source word
- CMP [SI],AL ;Source byte = <CR>?
- JE LEXSEARCH4 ;Found end of source word
- ;
- ;Check for end of destination word
- CMP ES:[DI],AL ;Destination byte = <CR>?
- JE LEXSEARCH3 ;No match -- go to next word
- ;
- ;Compare character by character
- DEC CX
- CMPSB ;Check for match
- JE LEXSEARCH2 ;Matched -- check next char
- JB LEXSEARCH5 ;Too high -- this is the place
- ;
- ;Scan for next <CR>
- LEXSEARCH3:
- REPNZ SCASB ;Scan until <CR>
- JMP LEXSEARCH1 ;Next word
- ;
- ;End of source word was found
- LEXSEARCH4:
- CMP [DI],AL ;Dest character = <CR>?
- JE LEXSEARCH6 ;End of destination word?
- ;
- ;Found a spot to insert the word
- LEXSEARCH5:
- MOV AL,0FFH ;Success
- JMP LEXSEARCHXIT
- ;
- ;Word already present
- LEXSEARCH6:
- MOV AL,00H ;Already there
- JMP LEXSEARCHXIT
- LEXSEARCHXIT:
- POP CX ;Restore registers
- POP DI
- POP SI
- RET
- LEXSEARCH ENDP
- ;------------------------------------------------------------------------------
- ;Routine to insert a word in an ordered list of words
- ;
- LEXINSERT PROC FAR
- PUSH AX ;Save register
- CALL LEXSEARCH ;Search for match
- CMP AL,0 ;Already there?
- JE LEXINSERTXIT ;Skip, if so
- CALL STRINSERT ;Insert the new word
- LEXINSERTXIT:
- POP AX ;Restore register
- RET
- LEXINSERT ENDP
- ;------------------------------------------------------------------------------
- ;Routine to compare two strings
- ;
- COMPARE PROC FAR
- PUSH SI ;Save registers
- PUSH DI
- PUSH CX
- REPZ CMPSB ;One compare does it !
- POP CX ;Restore registers
- POP DI
- POP SI
- COMPARE ENDP
- ;------------------------------------------------------------------------------
- ;Routine to switch two strings
- ;
- SWITCH PROC FAR
- PUSH SI ;Save registers
- PUSH DI
- PUSH CX
- PUSH AX
- CLD ;Forward direction
- SWITCH1:
- MOV AL,[DI] ;Get byte from destination
- MOVSB ;Move from source to dest
- MOV ES:[SI-1],AL ;Put byte in source
- LOOP SWITCH1 ;Loop back for more
- POP AX ;Restore registers
- POP CX
- POP DI
- POP SI
- RET
- SWITCH ENDP
- ;------------------------------------------------------------------------------
- ;Routine to sort a string array
- ;
- SORTB PROC FAR
- PUSH SI ;Save registers
- PUSH DI
- PUSH CX
- PUSH AX
- ;
- ;Adjust count for one less than number of items
- DEC CX ;Adjust the count
- ;
- ;Outer loop -- for SI = 1 to N-1
- SORTB1:
- PUSH CX ;Save the count
- MOV DI,SI ;Destination points to source
- ;
- ;Inner loop -- for DI = SI+1 to N
- SORTB2:
- PUSH CX ;Save the count
- ADD DI,DX ;Point to next destination
- MOV CX,DX ;Entry length
- CALL COMPARE ;Compare the strings
- JLE SORTB3 ;Skip if source <= destination
- CALL SWITCH ;Switch if not
- SORTB3:
- POP CX ;Restore the count
- LOOP SORTB2
- ADD SI,DX ;Point to next source
- POP CX ;Restore the count
- LOOP SORTB1
- SORTBXIT:
- POP AX ;Restore registers
- POP CX
- POP DI
- POP SI
- RET
- SORTB ENDP
- ;-----------------------------------------------------------------------------
- CODES ENDS
- ;
- END
- ;_____________________________________________________________________________
- ;>>>>> Physical EOF STRINGS.ASM <<<<<