Metropoli BBS
VIEWER: lst11-26.asm MODE: TEXT (ASCII)
;
; *** Listing 11-26 ***
;
; Determines whether two zero-terminated strings differ
; ignoring case-only differences, and if so where, using
; LODS.
;
	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
;
; Macro to convert the specified register to uppercase if
; it is lowercase.
;
TO_UPPER macro	REGISTER
	local	NotLower
	cmp	REGISTER,ch	;below 'a'?
	jb	NotLower	;yes, not lowercase
	cmp	REGISTER,cl	;above 'z'?
	ja	NotLower	;yes, not lowercase
	and	REGISTER,bl	;lowercase-convert to uppercase
NotLower:
	endm
;
; Compares two zero-terminated strings, ignoring differences
; that are only uppercase/lowercase differences.
;
; Input:
;	DS:SI = first zero-terminated string
;	ES:DI = second zero-terminated string
;
; Output:
;	DS:SI = pointer to first case-insensitive differing
;		location in first string, or 0 if the byte
;		wasn't found
;	ES:DI = pointer to first case-insensitive differing
;		location in second string, or 0 if the byte
;		wasn't found
;
; Registers altered: AX, BL, CX, DX, SI, DI
;
; Direction flag cleared
;
; Note: Does not handle strings that are longer than 64K
;	bytes or cross segment boundaries.
;
CompareStringsNoCase:
	cld
	mov	cx,'az'	;for fast register-register
			; comparison in the loop
	mov	bl,not 20h ;for fast conversion to
			; uppercase in the loop
CompareStringsLoop:
	lodsw		;get the next 2 bytes
	mov	dx,es:[di] ; from each string
	inc	di	;point to the next word in the
	inc	di	; second string
	TO_UPPER al	;convert the first byte from each
	TO_UPPER dl	; string to uppercase
	cmp	al,dl	;do the first bytes match?
	jnz	CompareStringsDifferent1 ;the strings differ
	and	al,al	;is the first byte the terminating
			; zero?
	jz	CompareStringsSame
			;yes, we're done with a match
	TO_UPPER ah	;convert the second byte from each
	TO_UPPER dh	; string to uppercase
	cmp	ah,dh	;do the second bytes match?
	jnz	CompareStringsDifferent ;the strings differ
	and	ah,ah	;is the second byte the terminating
			; zero?
	jnz	CompareStringsLoop
			;no, do the next 2 bytes
CompareStringsSame:
	sub	si,si	;return 0 pointers indicating that
	mov	di,si	; the strings are identical
	ret
CompareStringsDifferent1:
	dec	si	;point back to the second byte of
	dec	di	; the word we just compared
CompareStringsDifferent:
	dec	si	;point back to the first byte of the
	dec	di	; word we just compared
	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	CompareStringsNoCase	;and compare the
					; strings without
					; regard for case
	call	ZTimerOff

[ RETURN TO DIRECTORY ]