home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
assemblr
/
library
/
bluebook
/
strings.asm
< prev
next >
Wrap
Assembly Source File
|
1986-05-08
|
9KB
|
344 lines
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 <<<<<