Previous | Table of Contents | Next

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

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 LOOPs 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.

Previous | Table of Contents | Next

Graphics Programming Black Book © 2001 Michael Abrash