; ; *** Listing 11-28 *** ; ; Searches a text buffer for a sequence of bytes by checking ; for the sequence with CMPS starting at each byte of the ; buffer that potentially could start the sequence. ; jmp Skip ; ; Text buffer that we'll search. ; TextBuffer label byte db 'This is a sample text buffer, suitable ' db 'for a searching text of any sort... ' db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ' db 'End of text... ' TEXT_BUFFER_LENGTH equ ($-TextBuffer) ; ; Sequence of bytes that we'll search for. ; SearchSequence label byte db 'text...' SEARCH_SEQUENCE_LENGTH equ ($-SearchSequence) ; ; Searches a buffer for the first occurrence of a specified ; sequence of bytes. ; ; Input: ; CX = length of sequence of bytes to search for ; DX = length of buffer to search in ; DS:SI = start of sequence of bytes to search for ; ES:DI = start of buffer to search ; ; Output: ; ES:DI = pointer to start of first occurrence of ; desired sequence of bytes in the buffer, or ; 0:0 if the sequence wasn't found ; ; Registers altered: AX, BX, CX, DX, SI, DI, BP ; ; Direction flag cleared ; ; Note: Does not handle search sequences or text buffers ; that are longer than 64K bytes or cross segment ; boundaries. ; ; Note: Assumes non-zero length of search sequence (CX > 0), ; and search sequence shorter than 64K (CX <= 0ffffh). ; ; Note: Assumes buffer is longer than search sequence ; (DX > CX). Zero length of buffer is taken to mean ; that the buffer is 64K bytes long. ; FindSequence: cld mov bp,si ;set aside the sequence start ; offset mov ax,di ;set aside the buffer start offset mov bx,cx ;set aside the sequence length sub dx,cx ;difference between buffer and ; search sequence lengths inc dx ;# of possible sequence start bytes ; to check in the buffer FindSequenceLoop: mov cx,bx ;sequence length shr cx,1 ;convert to word for faster search jnc FindSequenceWord ;do word search if no odd ; byte cmpsb ;compare the odd byte jnz FindSequenceNoMatch ;odd byte doesn't match, ; so we havent' found the ; search sequence here FindSequenceWord: jcxz FindSequenceFound ;since we're guaranteed to ; have a non-zero length, ; the sequence must be 1 ; byte long and we've ; already found that it ; matched repz cmpsw ;check the rest of the ; sequence a word at a time ; for speed jz FindSequenceFound ;it's a match FindSequenceNoMatch: mov si,bp ;point to the start of the search ; sequence again inc ax ;advance to the next buffer start ; search location mov di,ax ;point DI to the next buffer start ; search location dec dx ;count down the remaining bytes to ; search in the buffer jnz FindSequenceLoop sub di,di ;return 0 pointer indicating that mov es,di ; the sequence was not found ret FindSequenceFound: mov di,ax ;point to the buffer location at ; which the first occurrence of the ; sequence was found ret ; Skip: call ZTimerOn mov si,offset SearchSequence ;point to search sequence mov cx,SEARCH_SEQUENCE_LENGTH ;length of search sequence mov di,seg TextBuffer mov es,di mov di,offset TextBuffer ;point to buffer to search mov dx,TEXT_BUFFER_LENGTH ;length of buffer to search call FindSequence ;search for the sequence call ZTimerOff