**LISTING 7.1 L7-1.ASM** ; Program to illustrate searching through a buffer of a specified ; length until either a specified byte or a zero byte is ; encountered. ; A standard loop terminated with LOOP is used. .model small .stack 100h .data ; Sample string to search through. SampleString labelbyte db ‘This is a sample string of a long enough length ' db ‘so that raw searching speed can outweigh any ' db ‘extra set-up time that may be required.',0 SAMPLE_STRING_LENGTH equ $-SampleString ; User prompt. Prompt db ‘Enter character to search for:$' ; Result status messages. ByteFoundMsg db 0dh,0ah db ‘Specified byte found.',0dh,0ah,‘$' ZeroByteFoundMsg db 0dh, 0ah db ‘Zero byte encountered.',0dh,0ah,‘$' NoByteFoundMsg db 0dh,0ah db ‘Buffer exhausted with no match.', 0dh, 0ah, ‘$' .code Startprocnear mov ax,@data ;point to standard data segment mov ds,ax mov dx,offset Prompt mov ah,9 ;DOS print string function int 21h ;prompt the user mov ah,1 ;DOS get key function int 21h ;get the key to search for mov ah,al ;put character to search for in AH mov cx,SAMPLE_STRING_LENGTH ;# of bytes to search mov si,offset SampleString ;point to buffer to search call SearchMaxLength ;search the buffer mov dx,offset ByteFoundMsg ;assume we found the byte jc PrintStatus ;we did find the byte ;we didn't find the byte, figure out ;whether we found a zero byte or ;ran out of buffer mov dx,offset NoByteFoundMsg ;assume we didn't find a zero byte jcxz PrintStatus ;we didn't find a zero byte mov dx,offset ZeroByteFoundMsg ;we found a zero byte PrintStatus: mov ah,9 ;DOS print string function int 21h ;report status mov ah,4ch ;return to DOS int 21h Startendp ; Function to search a buffer of a specified length until either a ; specified byte or a zero byte is encountered. ; Input: ; AH = character to search for ; CX = maximum length to be searched (must be > 0) ; DS:SI = pointer to buffer to be searched ; Output: ; CX = 0 if and only if we ran out of bytes without finding ; either the desired byte or a zero byte ; DS:SI = pointer to searched-for byte if found, otherwise byte ; after zero byte if found, otherwise byte after last ; byte checked if neither searched-for byte nor zero ; byte is found ; Carry Flag = set if searched-for byte found, reset otherwise SearchMaxLengthprocnear cld SearchMaxLengthLoop: lodsb ;get the next byte cmp al,ah ;is this the byte we want? jz ByteFound ;yes, we're done with success and al,al ;is this the terminating 0 byte? jz ByteNotFound ;yes, we're done with failure loop SearchMaxLengthLoop ;it's neither, so check the next ;byte, if any ByteNotFound: clc ;return "not found" status ret ByteFound: dec si ;point back to the location at which ;we found the searched-for byte stc ;return "found" status ret SearchMaxLengthendp end Start ### Unrolling Loops {#Heading7} Listing 7.2 takes a different tack, unrolling the loop so that four bytes are checked for each **LOOP** performed. The same instructions are used inside the loop in each listing, but Listing 7.2 is arranged so that three-quarters of the **LOOP**s are eliminated. Listings 7.1 and 7.2 perform exactly the same task, and they use the same instructions in the loop—the searching algorithm hasn't changed in any way—but we have sequenced the instructions differently in Listing 7.2, and that makes all the difference.