home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / asmutil / bluebook.zip / STRINGS.ASM < prev    next >
Assembly Source File  |  1986-05-08  |  9KB  |  344 lines

  1.                                       COMMENT ~
  2.  STRINGS.ASM -- String Manipulation Procedures
  3.  
  4.    From `BLUEBOOK of ASSEMBLY ROUTINES for the IBM PC & XT'
  5.          by Christopher L. Morgan
  6.          Copyright (C) 1984 by The Waite Group, Inc.
  7.  
  8.    Purpose: These routines manipulate strings.
  9.  
  10.    Contents:
  11.    ---------
  12.    COMPARE    --  Compare two strings
  13.    LEXINSERT    --  Lexigraphically insert
  14.    LEXSEARCH    --  Search a lexigraphically ordered list
  15.    LOWERCASE    --  Convert to lower case
  16.    SORTB    --  Bubble sort a string array
  17.    STRINSERT    --  Insert one string in another
  18.    STRSEARCH    --  Search for one string within another
  19.    SWITCH    --  Switch two strings
  20.    UPPERCASE    --  Convert to upper case
  21.  _____________________________________________________________________________
  22.                                           ~
  23. DATAS    SEGMENT    PUBLIC
  24.     DUMMY    DB    5 DUP(?)
  25. DATAS    ENDS 
  26. ;_____________________________________________________________________________ 
  27. CODES    SEGMENT
  28.     PUBLIC LOWERCASE,UPPERCASE,STRSEARCH,STRINSERT
  29.     PUBLIC LEXSEARCH,LEXINSERT,COMPARE,SWITCH,SORTB
  30.     ASSUME CS:CODES,DS:DATAS
  31. ;____________________________I/O ROUTINES_____________________________________
  32. ;Routine to convert string to lower case
  33. LOWERCASE    PROC    FAR
  34.     PUSH    BX                ;Save registers
  35.     PUSH    CX        
  36.     PUSH    AX
  37. ;
  38. ;Get the length
  39.     MOV    CX,[BX]                ;First two bytes contain length
  40.     INC    BX                ;Point to beginning of text
  41.     INC    BX
  42. ;
  43. ;Loop through the bytes of the string
  44. LOWERCASE1:
  45.     MOV    AL,[BX]                ;Get the character
  46.     CMP    AL,'A'                ;Below the upper case chars?
  47.     JB    LOWERCASE2            ;If so, skip
  48.     CMP    AL,'Z'                ;Above the upper case chars?
  49.     JA    LOWERCASE2            ;If so, skip
  50.     OR    AL,20H                ;OR bit 5 into the byte
  51. LOWERCASE2:
  52.     MOV    [BX],AL                ;Store the character
  53.     INC    BX                ;Point to next character
  54.     LOOP    LOWERCASE1        
  55.     POP    AX                ;Restore registers
  56.     POP    CX
  57.     POP    BX
  58.     RET
  59. LOWERCASE    ENDP
  60. ;------------------------------------------------------------------------------
  61. ;Routine to convert string to uppercase
  62. ;
  63. UPPERCASE    PROC    FAR
  64.     PUSH    BX                ;Save registers
  65.     PUSH    CX        
  66.     PUSH    AX
  67. ;
  68. ;Get the length
  69.     MOV    CX,[BX]                ;First two bytes contain length
  70.     INC    BX                ;Point to beginning of text
  71.     INC    BX
  72. ;
  73. ;Loop through the bytes of the string
  74. UPPERCASE1:
  75.     MOV    AL,[BX]                ;Get the character
  76.     CMP    AL,'a'                ;Below the lower case chars?
  77.     JB    UPPERCASE2            ;If so, skip
  78.     CMP    AL,'z'                ;Above the lower case chars?
  79.     JA    UPPERCASE2            ;If so, skip
  80.     AND    AL,5FH                ;Mask out bit number 5
  81. UPPERCASE2:
  82.     MOV    [BX],AL                ;Store the character
  83.     INC    BX                ;Point to next character
  84.     LOOP    UPPERCASE1        
  85.     POP    AX                ;Restore registers
  86.     POP    CX
  87.     POP    BX
  88.     RET
  89. UPPERCASE    ENDP
  90. ;------------------------------------------------------------------------------
  91. ;Routine to search for one string within another
  92. ;
  93. STRSEARCH    PROC    FAR
  94.     PUSH    SI                ;Save registers
  95.     PUSH    DI                
  96.     PUSH    CX
  97. ;
  98. ;Get length of destination and point to first byte
  99.     MOV    SI,DX                ;Use source index
  100.     LODSW                    ;Get the length of destination
  101.     MOV    CX,AX                ;Use the length as a count
  102.     MOV    DX,SI                ;Text begins here
  103. STRSEARCH1:
  104. ;
  105. ;Point indices to beginning of source and destination
  106.     MOV    SI,BX                ;Load source index
  107.     MOV    DI,DX                ;Load destination index
  108. ;
  109. ;Scan for a match
  110.     MOV    AL,[SI+2]            ;Get the first character
  111.     CLD                    ;Point forward
  112.     REPNZ    SCASB                ;Scan for match
  113.     JCXZ    STRSEARCH2            ;If no match, quit
  114. ;
  115. ;Got a match of first characters -- now check the entire string
  116.     MOV    DX,DI                ;Save current dest location
  117.     DEC    DI                ;Beginning of word
  118.     LODSW                    ;Get source length
  119.     XCHG    CX,AX                ;Use sourc cnt & save dest cnt
  120.     REPZ    CMPSB                ;Compare two strings
  121.     JCXZ    STRSEARCH3            ;It`s a match if no more source
  122. ;
  123. ;Continue the scan
  124.     XCHG    CX,AX                ;Use destination count
  125.     JMP    STRSEARCH1            ;Back for more scanning of dest
  126. ;
  127. ;No match is possible
  128. STRSEARCH2:
  129.     MOV    AL,0                ;Unsuccessful outcome
  130.     JMP    STRSEARCHXIT    
  131. ;
  132. ;Found a match
  133. STRSEARCH3:
  134.     DEC    DX                ;Point to beginning of match
  135.     MOV    AL,0FFH                ;Successful outcome
  136.     JMP    STRSEARCHXIT
  137. STRSEARCHXIT:
  138.     POP    CX                ;Restore registers
  139.     POP    DI            
  140.     POP    SI
  141.     RET
  142. STRSEARCH    ENDP
  143. ;------------------------------------------------------------------------------
  144. ;Routine to insert one string within another
  145. ;
  146. STRINSERT    PROC    FAR
  147.     PUSH    SI                ;Save registers
  148.     PUSH    DI                
  149.     PUSH    CX
  150.     PUSH    AX
  151. ;
  152. ;Find current end of destination string
  153.     MOV    SI,BP                ;Start of string
  154.     ADD    SI,ES:[SI]            ;Point to next to last byte
  155.     INC    SI                ;Adjust for length information
  156. ;
  157. ;Find new end of destination string and update length
  158.     MOV    DI,SI                ;Get old end of destination
  159.     MOV    AX,[BX]                ;Get length of source
  160.     ADD    DI,DX                ;New end of destination
  161.     ADD    ES:[BP],AX            ;New length of destination
  162. ;
  163. ;Move tail of destination string out of the way
  164.     MOV    CX,SI                ;SI + DX + 1 is the count
  165.     SUB    CX,DX        
  166.     INC    CX
  167.     STD                    ;Backward direction
  168. REP    MOVS    BYTE PTR[DI],ES:[SI]        ;Move the tail    
  169. ;
  170. ;Move source string into place
  171.     MOV    DI,DX                ;Destination of move
  172.     MOV    SI,BX                ;Source of movw
  173.     CLD                    ;Forward direction
  174.     LODSW                    ;Length of source
  175.     MOV    CX,AX                ;The count
  176.     REP    MOVSB                ;Make the string move
  177. STRINSERTXIT:
  178.     POP    AX                ;Restore registers    
  179.     POP    CX
  180.     POP    DI            
  181.     POP    SI
  182.     RET
  183. STRINSERT    ENDP
  184. ;------------------------------------------------------------------------------
  185. ;Routine to search for a word in an ordered list of words
  186. ;
  187. LEXSEARCH    PROC    FAR
  188. ;
  189.     PUSH    SI                ;Save register
  190.     PUSH    DI
  191.     PUSH    CX
  192. ;
  193. ;Point to beginning of list and get its length
  194.     MOV    DI,BP                ;Beginning of list
  195.     MOV    CX,[DI]                ;Get length
  196.     INC    DI        
  197.     INC    DI
  198. ;
  199. ;Compare source word with words in the list
  200. LEXSEARCH1:
  201.     MOV    DX,DI                ;Save beginning of dest word
  202.     CLD                    ;Forward direction
  203.     MOV    SI,BX                ;Point to beginning of source
  204.     INC    SI
  205.     INC    SI
  206. ;
  207. ;Compare source word with a word of the list
  208. LEXSEARCH2:
  209. ;
  210. ;Check for end of the list
  211.     JCXZ    LEXSEARCH5            ;End of list -- insert it
  212. ;
  213. ;Set up <CR> as scan character
  214.     MOV    AL,13                ;ASCII <CR>
  215. ;
  216. ;Check for end of source word
  217.     CMP    [SI],AL                ;Source byte = <CR>?
  218.     JE    LEXSEARCH4            ;Found end of source word
  219. ;
  220. ;Check for end of destination word
  221.     CMP    ES:[DI],AL            ;Destination byte = <CR>?
  222.     JE    LEXSEARCH3            ;No match -- go to next word
  223. ;
  224. ;Compare character by character
  225.     DEC    CX
  226.     CMPSB                    ;Check for match
  227.     JE    LEXSEARCH2            ;Matched -- check next char
  228.     JB    LEXSEARCH5            ;Too high -- this is the place
  229. ;
  230. ;Scan for next <CR>
  231. LEXSEARCH3:
  232.     REPNZ    SCASB                ;Scan until <CR>
  233.     JMP    LEXSEARCH1            ;Next word
  234. ;
  235. ;End of source word was found
  236. LEXSEARCH4:
  237.     CMP    [DI],AL                ;Dest character = <CR>?
  238.     JE    LEXSEARCH6            ;End of destination word?
  239. ;
  240. ;Found a spot to insert the word
  241. LEXSEARCH5:
  242.     MOV    AL,0FFH                ;Success
  243.     JMP    LEXSEARCHXIT
  244. ;
  245. ;Word already present
  246. LEXSEARCH6:
  247.     MOV    AL,00H                ;Already there
  248.     JMP    LEXSEARCHXIT
  249. LEXSEARCHXIT:
  250.     POP    CX                ;Restore registers
  251.     POP    DI
  252.     POP    SI
  253.     RET
  254. LEXSEARCH    ENDP
  255. ;------------------------------------------------------------------------------
  256. ;Routine to insert a word in an ordered list of words
  257. ;
  258. LEXINSERT    PROC    FAR
  259.     PUSH    AX                ;Save register
  260.     CALL    LEXSEARCH            ;Search for match
  261.     CMP    AL,0                ;Already there?
  262.     JE    LEXINSERTXIT            ;Skip, if so
  263.     CALL    STRINSERT            ;Insert the new word
  264. LEXINSERTXIT:
  265.     POP    AX                ;Restore register
  266.     RET    
  267. LEXINSERT    ENDP
  268. ;------------------------------------------------------------------------------
  269. ;Routine to compare two strings
  270. ;
  271. COMPARE    PROC    FAR
  272.     PUSH    SI                ;Save registers
  273.     PUSH    DI                
  274.     PUSH    CX
  275.     REPZ    CMPSB                ;One compare does it !
  276.     POP    CX                ;Restore registers
  277.     POP    DI
  278.     POP    SI
  279. COMPARE    ENDP    
  280. ;------------------------------------------------------------------------------
  281. ;Routine to switch two strings
  282. ;
  283. SWITCH    PROC    FAR
  284.     PUSH    SI                ;Save registers
  285.     PUSH    DI    
  286.     PUSH    CX
  287.     PUSH    AX
  288.     CLD                    ;Forward direction
  289. SWITCH1:
  290.     MOV    AL,[DI]                ;Get byte from destination
  291.     MOVSB                    ;Move from source to dest
  292.     MOV    ES:[SI-1],AL            ;Put byte in source
  293.     LOOP    SWITCH1                ;Loop back for more
  294.     POP    AX                ;Restore registers
  295.     POP    CX
  296.     POP    DI
  297.     POP    SI
  298.     RET
  299. SWITCH    ENDP
  300. ;------------------------------------------------------------------------------
  301. ;Routine to sort a string array
  302. ;
  303. SORTB    PROC    FAR
  304.     PUSH    SI                ;Save registers
  305.     PUSH    DI    
  306.     PUSH    CX
  307.     PUSH    AX
  308. ;
  309. ;Adjust count for one less than number of items
  310.     DEC    CX                ;Adjust the count
  311. ;
  312. ;Outer loop -- for SI = 1 to N-1
  313. SORTB1:
  314.     PUSH    CX                ;Save the count
  315.     MOV    DI,SI                ;Destination points to source
  316. ;
  317. ;Inner loop -- for DI = SI+1 to N
  318. SORTB2:
  319.     PUSH    CX                ;Save the count
  320.     ADD    DI,DX                ;Point to next destination
  321.     MOV    CX,DX                ;Entry length
  322.     CALL    COMPARE                ;Compare the strings
  323.     JLE    SORTB3                ;Skip if source <= destination
  324.     CALL    SWITCH                ;Switch if not
  325. SORTB3:
  326.     POP    CX                ;Restore the count 
  327.     LOOP    SORTB2
  328.     ADD    SI,DX                ;Point to next source
  329.     POP    CX                ;Restore the count
  330.     LOOP    SORTB1
  331. SORTBXIT:
  332.     POP    AX                ;Restore registers
  333.     POP    CX
  334.     POP    DI
  335.     POP    SI
  336.     RET
  337. SORTB    ENDP
  338. ;-----------------------------------------------------------------------------
  339. CODES    ENDS
  340. ;
  341.     END
  342. ;_____________________________________________________________________________ 
  343. ;>>>>> Physical EOF STRINGS.ASM <<<<<
  344.