Tvůrce webu je i pro tebe! Postav třeba web. Bez grafika. Bez kodéra. Hned.
wz

Obsah / Utility / TEXT / TextComp

Zdrojový kód: INCLUDE\UTIL\TEXT.INC, UTIL\TEXT.ASM


TextComp - Alfabetické porovnání textů

Funkce TextComp porovná dva texty abecedně - bez rozlišení velkých a malých písmen.


; -----------------------------------------------------------------------------
;                    Compare text strings alphabetically
; -----------------------------------------------------------------------------
; INPUT:	EAX = first text string TEXT
;		EBX = second text string TEXT
;		EDI = pointer to nationality descriptor NATIONAL (NULL=default)
; OUTPUT:	EAX:	1 = first string is greater (later) than second string
;			0 = strings are equals
;			-1 = first string is smaller (earlier) than second one
; NOTES:	Comparison is not case sensitive.
; -----------------------------------------------------------------------------

Na vstupu funkce obsahuje registr EAX ukazatel na první textovou proměnnou, registr EBX ukazatel na druhou textovou proměnnou a registr EDI ukazatel na popisovač národnostních informací NATIONAL (nebo NULL, pokud se má použít implicitní popisovač). V registru EAX navrátí funkce číslo 1, pokud je první text abecedně větší (abecedně pozdější) než druhý text, číslo 0 pokud jsou texty shodné a číslo -1 pokud je první text menší (abecedně dřívější) než druhý text.


; ------------- Push registers

TextComp:	push	ecx		; push ECX
		push	edx		; push EDX
		push	esi		; push ESI
		push	edi		; push EDI
		push	ebp		; push EBP

; ------------- Check if strings are identical

		mov	esi,[eax]	; ESI <- data buffer of first text
		cmp	esi,[ebx]	; compare data buffers
		je	TextComp9	; string are identical

............................

; ------------- String are identical

TextComp9:	xor	eax,eax		; EAX <- 0
		jmp	short TextComp4

Na začátku funkce se porovnají ukazatele na datové buffery prvního a druhého textu. Pokud jsou ukazatele shodné, jedná se o identický text a funkce se rychle ukončí s návratovým kódem 0.


; ------------- Prepare nationality descriptor (-> EDI)

		or	edi,edi		; use default nationality?
		jnz	TextComp1	; no default nationality
		DEFAULT_NAT edi		; EDI <- get default nationality

Pokud je ukazatel na popisovač národnostních informací nulový, připraví se pomocí makra DEFAULT_NAT implicitní popisovač národnostních informací.


; ------------- Prepare registers

TextComp1:	xchg	eax,ecx		; ECX <- first text string
		xor	esi,esi		; ESI <- 0, pointer of first string
		xor	edx,edx		; EDX <- 0, pointer of second string

Připraví se registry ro operaci porovnání textů - registr ECX bude obsahovat adresu prvního textového řetězce, ESI je ukazatel pozice prvního textu a EDX je ukazatel pozice druhého textu.


; ------------- Get sorting value of character of first string

TextComp2:	xchg	ecx,ebx		; EBX <- first string, ECX <- second
		xchg	edx,esi		; EDX <- pointer to first string
		call	TextGetChar	; get first character (-> EAX)
		xchg	ecx,ebx		; ECX <- first string, EBX <- second
		xchg	edx,esi		; ESI <- pointer to first string
		jc	TextComp6	; end of first string
		call	UniCharSortCap	; get sorting value (-> EAX)
		xchg	eax,ebp		; EBP <- save first character

Dále se postupuje v porovnání textů znak po znaku. Z prvního textového řetězce se funkcí TextGetChar načte jeden znak (v kódu Unicode) a znak se převede funkcí UniCharSortCap na třídicí hodnotu, třídicí hodnota se uchová do registru EBP.


TextComp6:	call	TextGetChar	; get second character
		sbb	eax,eax		; EAX <- 0 if smaller, -1 if equal
		neg	eax		; EAX <- 0 if smaller, 1 if equal
		dec	eax		; EAX <- -1 if smaller, 0 if equal
		jmp	short TextComp4

Pokud bylo dosaženo konce prvního řetězce (funkce TextGetChar navrátila příznak CY), načte se funkcí TextGetChar znak z druhého řetězce. Z navráceného příznaku chyby CF se odvodí návratový kód tak, že pokud funce navrátila platný znak (tj. navrátila příznak NC), funkce se ukončí s návratovým kódem -1, tj. první text je menší. Pokud funkce navrátila příznak chyby CY, navrátí se kód 0, tj. texty jsou shodné.


; ------------- Get sorting value of character of second string

		call	TextGetChar	; get second character (-> EAX)
		jc	TextComp8	; end of second string
		call	UniCharSortCap	; get sorting value (-> EAX)

............................

; ------------- End of second string (EAX <- 1, first string is greater)

TextComp8:	xor	eax,eax		; EAX <- 0
		jmp	short TextComp3

V případě platnosti znaku z prvního řetězce se načte znak z druhého řetězce. Pokud je druhý znak neplatný /tj. funkce navrátí příznak CY), funkce se ukončí s návratovým kódem 1, tj první řetězec je větší než druhý. Je-li znak platný, převede se funkcí UniCharSortCap na třídicí hodnotu.


; ------------- Compare characters

		cmp	ebp,eax		; compare characters
		je	TextComp2	; characters are identical, try next

; ------------- Get result (here is CY if FIRST < SECOND)

		sbb	eax,eax		; EAX <- 0 if greater, -1 if smaller
		shl	eax,1		; EAX <- 0 if greater, -2 if smaller
TextComp3:	inc	eax		; EAX <- 1 if greater, -1 if smaller

; ------------- Pop registers

TextComp4:	pop	ebp		; pop EBP
		pop	edi		; pop EDI
		pop	esi		; pop ESI
		pop	edx		; pop EDX
		pop	ecx		; pop ECX
		ret		

Jsou-li znaky z obou řetězců platné, porovnají se jejich třídicí hodnoty. Jsou-li třídicí hodnoty shodné, pokračuje se porovnáním dalšího znaku. V případě neshody se funkce ukončí s návratovým kódem 1 nebo -1.


Obsah / Utility / TEXT / TextComp