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

Obsah / Utility / TEXT / TextFindByteFirst, TextFindByte

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


TextFindByteFirst, TextFindByte - Vyhledání prvního/dalšího bajtu v textu

Funkce TextFindByteFirst vyhledá v textu první výskyt daného bajtu. Funkce TextFindByte vyhledá první výskyt bajtu od dané pozice v textu (včetně).


; -----------------------------------------------------------------------------
;                    Find 1 byte in text in forward direction
; -----------------------------------------------------------------------------
; INPUT:	AL = byte to find
;		EBX = pointer to TEXT
;		EDX = start offset (it can be out of range)
; OUTPUT:	EDX = offset of found byte (or EDX = -1 if data not found)
;		CY = data not found (EDX = -1)
; NOTES:	Set EDX to 0 to find first occurrence of the byte.
; -----------------------------------------------------------------------------

; ------------- Find first occurrence of 1 byte

TextFindByteFirst:
		xor	edx,edx		; EDX <- 0, find first occurrence

Na vstupu funkce obsahuje registr AL hodnotu vyhledávaného bajtu. 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 bajt vyhledáván. V případě funkce TextFindByteFirst je obsah registru EDX nejdříve vynulován, čímž se zajistí nastavení ukazatele na začátek textu.

Je-li bajt v textu nalezen, je navrácena v registru EDX pozice (offset) bajtu v textu a příznak CF je vynulován. Není-li bajt nalezen, je v registru EDX navrácena hodnota -1 a je navrácen příznak chyby CY.


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

TextFindByte:	push	ecx		; push ECX
		push	edi		; push EDI

; ------------- Limit minimal offset to 0 (-> EDX)

		or	edx,edx		; is start offset negative?
		sets	cl		; CL <- 0 if EDX >= 0, 1 if EDX < 0
		movzx	ecx,cl		; ECX <- 0 if EDX >= 0, 1 if EDX < 0
		dec	ecx		; ECX <- -1 if EDX >= 0, 0 if EDX < 0
		and	edx,ecx		; EDX <- 0 if EDX < 0

Po úschově 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ý.


; ------------- Get text length (-> ECX) and text address (-> EDI)

		mov	edi,[ebx]	; EDI <- data buffer
		mov	ecx,[edi+TEXT_Length] ; ECX <- length of text
		lea	edi,[edi+TEXT_Text+edx] ; EDI <- start pointer

Do registru ECX se připraví celková délka prohledávaného textu (v bajtech) a do registru EDI ukazatel na začátek prohledávaného textu (posunutý na počáteční pozici k prohledání).


; ------------- Find data

		sub	ecx,edx		; ECX <- remaining data
		jle	short TextFindWord6 ; data not found
		repne	scasb		; find data
		jne	short TextFindWord6 ; data not found

Odečtením pozice počátku textu zůstane v registru ECX počet zbylých bajtů 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. Část kódu pro obsluhu chyby je společná s funkcí TextFindWord. Je-li počet bajtů kladný, vyhledá se bajt v textu. 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.


; ------------- Get offset of data

		inc	ecx		; ECX <- return found data
		mov	edx,[ebx]	; EDX <- data buffer
		mov	edx,[edx+TEXT_Length] ; EDX <- text length
		sub	edx,ecx		; EDX <- data offset (it sets NC)

; ------------- OK: Pop registers (here is NC)

		pop	edi		; pop EDI
		pop	ecx		; pop ECX
		ret

Je-li bajt v textu nalezen, obsahuje registr ECX počet zbylých bajtů. Inkrementací a odečtením od celkové délky textu se obdrží v registru EDX offset nalezeného bajtu v textu. Funkce je ukončena s vynulovaným příznakem chyby NC.


Obsah / Utility / TEXT / TextFindByteFirst, TextFindByte