Category : Assembly Language Source Code
Archive   : ZENASM.ZIP
Filename : LST13-27.ASM

 
Output of file : LST13-27.ASM contained in archive : ZENASM.ZIP

;
; *** Listing 13-27 ***
;
; Determines whether two zero-terminated strings differ, and
; if so where, using LODS/SCAS and partial in-line code.
;
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: AX, SI, DI
;
; Direction flag cleared
;
; Note: Does not handle strings that are longer than 64K
; bytes or cross segment boundaries.
;
CompareStrings:
cld
CompareStringsLoop:
;
; First 7 repetitions of partial in-line code.
;
rept 7
lodsw ;get the next 2 bytes
and al,al ;is the first byte the terminating
; zero?
jz CompareStringsFinalByte
;yes, so there's only one byte left
; to check
scasw ;compare this word
jnz CompareStringsDifferent ;the strings differ
and ah,ah ;is the second byte the terminating
; zero?
jz CompareStringsSame
;yes, we've got a match
endm
;
; Final repetition of partial in-line code.
;
lodsw ;get the next 2 bytes
and al,al ;is the first byte the terminating
; zero?
jz CompareStringsFinalByte
;yes, so there's only one byte left
; to check
scasw ;compare this word
jnz CompareStringsDifferent ;the strings differ
and ah,ah ;is the second byte the terminating
; zero?
jnz CompareStringsLoop ;no, continue comparing
;the strings are the same
CompareStringsSame:
sub si,si ;return 0 pointers indicating that
mov di,si ; the strings are identical
ret
CompareStringsFinalByte:
scasb ;does the terminating zero match in
; the 2 strings?
jz CompareStringsSame ;yes, the strings match
dec si ;point back to the differing byte
dec di ; in each string
ret
CompareStringsDifferent:
;the strings are different, so we
; have to figure which byte in the
; word just compared was the first
; difference
dec si
dec si ;point back to the first byte of the
dec di ; differing word in each string
dec di
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
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