home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / asmutil / zendisk2.zip / LST11-29.ASM < prev    next >
Assembly Source File  |  1990-02-15  |  5KB  |  152 lines

  1. ;
  2. ; *** Listing 11-29 ***
  3. ;
  4. ; Searches a text buffer for a sequence of bytes by using
  5. ; REPNZ SCASB to identify bytes in the buffer that
  6. ; potentially could start the sequence and then checking
  7. ; only starting at those qualified bytes for a match with
  8. ; the sequence by way of REPZ CMPS.
  9. ;
  10.     jmp    Skip
  11. ;
  12. ; Text buffer that we'll search.
  13. ;
  14. TextBuffer    label    byte
  15.     db    'This is a sample text buffer, suitable '
  16.     db    'for a searching text of any sort... '
  17.     db    'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 '
  18.     db    'End of text... '
  19. TEXT_BUFFER_LENGTH    equ    ($-TextBuffer)
  20. ;
  21. ; Sequence of bytes that we'll search for.
  22. ;
  23. SearchSequence    label    byte
  24.     db    'text...'
  25. SEARCH_SEQUENCE_LENGTH    equ    ($-SearchSequence)
  26. ;
  27. ; Searches a buffer for the first occurrence of a specified
  28. ; sequence of bytes.
  29. ;
  30. ; Input:
  31. ;    CX = length of sequence of bytes to search for
  32. ;    DX = length of buffer to search in
  33. ;    DS:SI = start of sequence of bytes to search for
  34. ;    ES:DI = start of buffer to search
  35. ;
  36. ; Output:
  37. ;    ES:DI = pointer to start of first occurrence of
  38. ;        desired sequence of bytes in the buffer, or
  39. ;        0:0 if the sequence wasn't found
  40. ;
  41. ; Registers altered: AL, BX, CX, DX, SI, DI, BP
  42. ;
  43. ; Direction flag cleared
  44. ;
  45. ; Note: Does not handle search sequences or text buffers
  46. ;    that are longer than 64K bytes or cross segment
  47. ;    boundaries.
  48. ;
  49. ; Note: Assumes non-zero length of search sequence (CX > 0),
  50. ;    and search sequence shorter than 64K (CX <= 0ffffh).
  51. ;
  52. ; Note: Assumes buffer is longer than search sequence
  53. ;    (DX > CX). Zero length of buffer (DX = 0) is taken
  54. ;    to mean that the buffer is 64K bytes long.
  55. ;
  56. FindSequence:
  57.     cld
  58.     lodsb        ;get the first byte of the search
  59.             ; sequence, which we'll leave in AL
  60.             ; for faster searching
  61.     mov    bp,si    ;set aside the sequence start
  62.             ; offset plus one
  63.     dec    cx    ;we don't need to compare the first
  64.             ; byte of the sequence with CMPS,
  65.             ; since we'll do it with SCAS
  66.     mov    bx,cx    ;set aside the sequence length
  67.             ; minus 1
  68.     sub    dx,cx    ;difference between buffer and
  69.             ; search sequence lengths plus 1
  70.             ; (# of possible sequence start
  71.             ; bytes to check in the buffer)
  72.     mov    cx,dx    ;put buffer search length in CX
  73.     jnz    FindSequenceLoop ;start normally if the
  74.                 ; buffer isn't 64Kb long
  75.     dec    cx    ;the buffer is 64K bytes long-we
  76.             ; have to check the first byte
  77.             ; specially since CX = 0 means
  78.             ; "do nothing" to REPNZ SCASB
  79.     scasb        ;check the first byte of the buffer
  80.     jz    FindSequenceCheck ;it's a match for 1 byte,
  81.                 ; at least-check the rest
  82. FindSequenceLoop:
  83.     repnz    scasb    ;search for the first byte of the
  84.             ; search sequence
  85.     jnz    FindSequenceNotFound
  86.             ;it's not found, so there are no
  87.             ; possible matches
  88. FindSequenceCheck:
  89.             ;we've got a potential (first byte)
  90.             ; match-check the rest of this
  91.             ; candidate sequence
  92.     push    di    ;remember the address of the next
  93.             ; byte to check in case it's needed
  94.     mov    dx,cx    ;set aside the remaining length to
  95.             ; search in the buffer
  96.     mov    si,bp    ;point to the rest of the search
  97.             ; sequence
  98.     mov    cx,bx    ;sequence length (minus first byte)
  99.     shr    cx,1    ;convert to word for faster search
  100.     jnc    FindSequenceWord ;do word search if no odd
  101.                 ; byte
  102.     cmpsb        ;compare the odd byte
  103.     jnz    FindSequenceNoMatch
  104.                 ;odd byte doesn't match,
  105.                 ; so we haven't found the
  106.                 ; search sequence here
  107. FindSequenceWord:
  108.     jcxz    FindSequenceFound
  109.             ;since we're guaranteed to have
  110.             ; a non-zero length, the
  111.             ; sequence must be 1 byte long
  112.             ; and we've already found that
  113.             ; it matched
  114.     repz    cmpsw    ;check the rest of the sequence a
  115.             ; word at a time for speed
  116.     jz    FindSequenceFound ;it's a match
  117. FindSequenceNoMatch:
  118.     pop    di    ;get back the pointer to the next
  119.             ; byte to check
  120.     mov    cx,dx    ;get back the remaining length to
  121.             ; search in the buffer
  122.     and    cx,cx    ;see if there's anything left to
  123.             ; check
  124.     jnz    FindSequenceLoop ;yes-check next byte
  125. FindSequenceNotFound:
  126.     sub    di,di    ;return 0 pointer indicating that
  127.     mov    es,di    ; the sequence was not found
  128.     ret
  129. FindSequenceFound:
  130.     pop    di    ;point to the buffer location at
  131.     dec    di    ; which the first occurrence of the
  132.             ; sequence was found (remember that
  133.             ; earlier we pushed the address of
  134.             ; the byte after the potential
  135.             ; sequence start)
  136.     ret
  137. ;
  138. Skip:
  139.     call    ZTimerOn
  140.     mov    si,offset SearchSequence
  141.                 ;point to search sequence
  142.     mov    cx,SEARCH_SEQUENCE_LENGTH
  143.                 ;length of search sequence
  144.     mov    di,seg TextBuffer
  145.     mov    es,di
  146.     mov    di,offset TextBuffer
  147.                 ;point to buffer to search
  148.     mov    dx,TEXT_BUFFER_LENGTH
  149.                 ;length of buffer to search
  150.     call    FindSequence    ;search for the sequence
  151.     call    ZTimerOff
  152.