Metropoli BBS
VIEWER: lst11-25.asm MODE: TEXT (ASCII)
;
; *** Listing 11-25 ***
;
; Determines whether two zero-terminated strings differ, and
; if so where, using LODS/SCAS.
;
	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:
	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

[ RETURN TO DIRECTORY ]