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

Obsah / Utility / TEXT / TextRight

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


TextRight - Pravá část textu

Funkce TextRight navrátí pravou část textu, tedy konec textu o dané délce.


; -----------------------------------------------------------------------------
;                            Get right part of text
; -----------------------------------------------------------------------------
; INPUT:	EAX = pointer to source TEXT
;		EBX = pointer to destination TEXT
;		ECX = length of right part of text (it may be out of range)
; OUTPUT:	CY = memory error, destination TEXT becomes empty
; NOTES:	It limits length to a valid range.
;		Source and destination may be identical.
; -----------------------------------------------------------------------------

Na vstupu funkce obsahuje registr EAX ukazatel na zdrojovou textovou proměnnou, EBX ukazatel na cílovou textovou proměnnou a ECX délku pravé části textu (v bajtech). Délka textu může být mimo platný rozsah. V případě chyby paměti funkce navrátí příznak chyby CY a cílový text se nastaví jako prázdný. Zdrojová a cílová proměnná mohou být identické.


; ------------- Check if source and destination is identical

TextRight:	cmp	eax,ebx		; is source and destination identical?
		je	TextRight8	; source is identical with destination

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

; ------------- Identical source and destination variable (here is EAX == EBX)

TextRight8:	push	ecx		; push ECX
		push	edx		; push EDX
		mov	edx,[ebx]	; EDX <- data buffer
		sub	ecx,[edx+TEXT_Length] ; ECX <- -length of deleted data
		neg	ecx		; ECX = length of deleted data
		call	TextDelStart	; delete start of text
		pop	edx		; pop EDX
		pop	ecx		; pop ECX
		jc	TextLeft9	; memory error
		ret

Na začátku funkce se porovnáním ukazatelů ověří, zda cílová a zdrojová textová proměnná nejsou identické. Pokud ano, provede se kopie textu zvláštní obsluhou a to tak, že se zruší část textu před kopírovanou částí. V případě chyby bude cílový text vyprázdněn.


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

		push	eax		; push EAX
		push	ecx		; push ECX
		push	esi		; push ESI
		push	edi		; push EDI

; ------------- Empty destination text variable

		call	TextEmpty	; empty text

Po úschově registrů je cílový text vyprázdněn pro případ návratu s chybou.


; ------------- Check text length

		mov	esi,[eax]	; ESI <- source data buffer
		mov	eax,[esi+TEXT_Length] ; EAX <- source text length
		cmp	ecx,eax		; check text length
		ja	TextRight6	; limit text length
		xchg	eax,ecx		; EAX <- dest length, ECX <- src length

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

; ------------- Limit text length

TextRight6:	or	ecx,ecx		; check minimal text length
		js	TextRight4	; invalid text length
		mov	ecx,eax		; ECX <- source length
		jmp	short TextRight2

Do registru ESI je připraven ukazatel na buffer zdrojového textu a do registru EAX délka zdrojového textu. Porovnáním s požadovanou délkou textu v registru ECX je ověřena platnost délky. Pokud požadovaná délka přesahuje skutečnou délku, bude délka textu omezena. Jedná-li se o záporné číslo, funkce se ukončí, protože výsledkem zůstává prázdný text. Je-li délka nekladná, omezí se na skutečnou délku textu.


; ------------- Create destination buffer (it need not be detached)

TextRight2:	or	eax,eax		; is text empty?
		jz	TextRight4	; text is empty
		call	TextNew		; create data buffer
		jc	TextRight4	; memory error

Registr EAX nyní obsahuje požadovanou délku textu. Je-li požadovaná délka nula, funkce se může ihned ukončit, cílový text je již vyprázdněný. Jinak se vytvoří pomocí funkce TextNew nový textový buffer pro požadovanou délku textu. Adresa bufferu se uloží do cílové proměnné EBX. Původní obsah proměnné EBX není potřeba odpojovat, protože se jednalo o prázdný konstantní text, který nevyžaduje manipulaci s čítačem referencí.


; ------------- Prepare offset of text (-> ECX)

		sub	ecx,eax		; ECX <- offset of text

; ------------- Prepare buffers

		lea	esi,[esi+ecx+TEXT_Text]	; ESI <- source start of text
		mov	edi,[ebx]	; EDI <- destination data buffer
		add	edi,byte TEXT_Text ; EDI <- dest. start of text

; ------------- Copy text (it exits with NC)

		mov	ecx,eax		; ECX <- length of text
		shr	ecx,2		; ECX <- length of text in DWORDs
		rep	movsd		; shift text in DWORDs
		and	eax,byte 3	; EAX <- rest in last DWORD
		xchg	eax,ecx		; ECX <- rest in last DWORD
		rep	movsb		; copy rest of text

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

TextRight4:	pop	edi		; pop EDI
		pop	esi		; pop ESI
		pop	ecx		; pop ECX
		pop	eax		; pop EAX
		ret

Do registru ECX se připraví offset začátku pravé části textu. Registr ESI se posune na začátek zdrojového textu. Do registru EDI se připraví začátek bufferu cílového textu. Text se zkopíruje ze zdrojového do cílového bufferu - nejdříve po celých dvojslovech a pak zbylá data v posledním dvojslovu.


Obsah / Utility / TEXT / TextRight