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