Obsah / Utility / TEXT / TextFindFirst, TextFind
Zdrojový kód: INCLUDE\UTIL\TEXT.INC, UTIL\TEXT.ASM
TextFindFirst, TextFind - Vyhledání prvního/dalšího řetězce v textu
Funkce TextFindFirst vyhledá v textu první výskyt daného textového řetězce. Funkce TextFind vyhledá první výskyt textového řetězce od dané pozice v textu (včetně).
|
Na vstupu funkce obsahuje registr EAX ukazatel na textovou proměnnou s hledaným textovým řetězcem. Registr EBX obsahuje ukazatel na textovou proměnnou s textem k prohledání. Registr EDX obsahuje počáteční offset v textu, od kterého bude textový řetězec vyhledáván. V případě funkce TextFindFirst je obsah registru EDX nejdříve vynulován, čímž se zajistí nastavení ukazatele na začátek textu.
Referenční čítač TEXT_Ref hledaného textového řetězce se ve funkci ignoruje a to je využito v některých funkcích které tuto funkci volají - např. TextFindChar a TextFindCharRev.
Je-li textový řetězec v textu nalezen, je navrácena v registru EDX pozice (offset) řetězce v textu a příznak CF je vynulován. Není-li textový řetězec nalezen, je v registru EDX navrácena hodnota -1 a je navrácen příznak chyby CY.
|
Po úschově první části registrů se funkce pokusí provést hledání zrychleně. Do registru EBP si připraví délku hledaného textu. Pokud má hledaný řetězec nulovou délku, funkce se ihned ukončí s vynulovaným příznakem chyby NC znamenajícím, že nulový řetězec je nalezen vždy. Pro délku řetězce 1 se do registru AL připraví první bajt řetězce a hledání se provede funkcí TextFindByte. Pro délku řetězce 2 se do registru AH navíc připraví druhý bajt řetězce a hledání se provede funkcí TextFindWord. Jinak se použije pomalé hledání.
|
Po úschově druhé části registrů bude omezen minimální počáteční offset v textu (aby neukazoval pod hodnotu 0). Pro zrychlení kódu se nepoužije instrukce skoku, ale využijí se operace s registry. Po testu obsahu registru EDX se nastaví obsah registru CL na hodnotu 0, pokud byl offset nezáporný, nebo 1, pokud byl offset záporný. Po rozšíření hodnoty do registru ECX a dekrementaci bude registr ECX obsahovat hodnotu -1 (tj. 0FFFFFFFFh) pokud byl offset nezáporný, nebo hodnotu 0, pokud byl offset záporný. Zamaskováním offsetu v registru EDX registrem ECX se zajistí vynulování obsahu registru EDX v případě, že offset byl záporný.
|
Do registru ECX se připraví celková délka prohledávaného textu (v bajtech) snížená o délku řetězce a snížená o 1 (což je rezerva pro zbytek řetězce bez prvního bajtu) a do registru EDI ukazatel na začátek prohledávaného textu (posunutý na počáteční pozici k prohledání). Odečtením pozice počátku textu zůstane v registru ECX počet zbylých pozic k prohledání - při podtečení se funkce ukončí s navrácením příznaku chyby CY a s hodnotou -1 v registru EDX.
|
Je-li počet bajtů kladný, vyhledá se první bajt řetězce v textu - je obsažen v registru AL. Nebyl-li nalezen (instrukce SCASB navrátí příznak NZ) funkce se opět ukončí s příznakem chyby CY a hodnotou -1 v registru EDX. Pokud byl první bajt nalezen, otestuje se druhý bajt - ten se nachází v registru AH. Jestliže druhý bajt nesouhlasí, pokračuje se vyhledáváním prvního bajtu od další pozice v textu.
|
V případě nalezení prvních 2 bajtů hledaného řetězce se provede porovnání zbytku řetězce. Uchovají se ukazatele pozice v textu a porovná se zbytek řezězce - pro zrychlení se porovnání provádí nejdříve po dvojslovech (instrukce cmpsd) a nakonec se porovnají zbylé bajty v posledním dvojslově řetězce. Navrátí se registry a pokud řetězec nesouhlasí, pokračuje se v hledání další pozicí v textu.
|
Je-li řetězec úspěšně nalezen, obnoví se v registru ECX počet zbylých bajtů do konce textu, odečtením od délky textu se v registru EDX obdrží offset nalezené pozice v textu a funkce se ukončí s vynulovaným příznakem chyby NC.
Obsah / Utility / TEXT / TextFindFirst, TextFind