home *** CD-ROM | disk | FTP | other *** search
- ;
- ; *** Listing 11-24 ***
- ;
- ; Determines whether two zero-terminated strings differ, and
- ; if so where, using REP SCASB to find the terminating zero
- ; to determine one string length, and then using REPZ CMPSW
- ; to compare the strings.
- ;
- jmp Skip
- ;
- TestString1 label byte
- db 'This is a test string that is '
- db 'z'
- db 'terminated with a zero byte...',0
- TestString2 label byte
- db 'This is a test string that is '
- db 'a'
- db 'terminated with a zero byte...',0
- ;
- ; Compares two zero-terminated strings.
- ;
- ; Input:
- ; DS:SI = first zero-terminated string
- ; ES:DI = second zero-terminated string
- ;
- ; Output:
- ; DS:SI = pointer to first differing location in
- ; first string, or 0 if the byte wasn't found
- ; ES:DI = pointer to first differing location in
- ; second string, or 0 if the byte wasn't found
- ;
- ; Registers altered: AL, CX, DX, SI, DI
- ;
- ; Direction flag cleared
- ;
- ; Note: Does not handle strings that are longer than 64K
- ; bytes or cross segment boundaries.
- ;
- ; Note: If there is no terminating zero in the first 64K-1
- ; bytes of a string, the string is treated as if byte
- ; 64K is a zero without checking, since if it isn't
- ; the string isn't zero-terminated at all.
- ;
- CompareStrings:
- mov dx,di ;set aside the start of the second
- ; string
- sub al,al ;we'll search for zero in the second
- ; string to see how long it is
- mov cx,0ffffh ;long enough to handle any string
- ; up to 64K-1 bytes in length. Any
- ; longer string will be treated as
- ; if byte 64K is zero
- cld
- repnz scasb ;find the terminating zero
- not cx ;length of string in bytes, including
- ; the terminating zero except in the
- ; case of a string that's exactly 64K
- ; long including the terminating zero
- mov di,dx ;get back the start of the second
- ; string
- shr cx,1 ;get count in words
- jnc CompareStringsWord
- ;if there's no odd byte, go directly
- ; to comparing a word at a time
- cmpsb ;compare the odd bytes of the
- ; strings
- jnz CompareStringsDifferentByte
- ;we've already found a difference
- CompareStringsWord:
- ;there's no need to guard against
- ; CX=0 here, since we know that if
- ; CX=0 here, the preceding CMPSB
- ; must have successfully compared
- ; the terminating zero bytes of the
- ; strings (which are the only bytes
- ; of the strings), and the Zero flag
- ; setting of 1 from CMPSB will be
- ; preserved by REPZ CMPSW if CX=0,
- ; resulting in the correct
- ; conclusion that the strings are
- ; identical
- repz cmpsw ;compare the rest of the strings a
- ; word at a time for speed
- jnz CompareStringsDifferent ;they're not the same
- sub si,si ;return 0 pointers indicating that
- mov di,si ; the strings are identical
- ret
- CompareStringsDifferent:
- ;the strings are different, so we
- ; have to figure which byte in the
- ; word just compared was the first
- ; difference
- dec si ;point back to the second byte of
- dec di ; the differing word in each string
- dec si ;point back to the differing byte in
- dec di ; each string
- lodsb
- scasb ;compare that first byte again
- jz CompareStringsDone
- ;if the first bytes are the same,
- ; then it must have been the second
- ; bytes that differed. That's where
- ; we're pointing, so we're done
- CompareStringsDifferentByte:
- dec si ;the first bytes differed, so point
- dec di ; back to them
- CompareStringsDone:
- ret
- ;
- Skip:
- call ZTimerOn
- mov si,offset TestString1 ;point to one string
- mov di,seg TestString2
- mov es,di
- mov di,offset TestString2 ;point to other string
- call CompareStrings ;and compare the strings
- call ZTimerOff