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

Obsah / Utility / TEXT / TextLeft

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


TextLeft - Levá část textu

Funkce TextLeft navrátí levou část textu, tedy začátek textu o dané délce.


; -----------------------------------------------------------------------------
;                            Get left part of text
; -----------------------------------------------------------------------------
; INPUT:	EAX = pointer to source TEXT
;		EBX = pointer to destination TEXT
;		ECX = length of left 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 levé čá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

TextLeft:	cmp	eax,ebx		; is source and destination identical?
		je	TextLeft8	; source is identical with destination

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

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

TextLeft8:	push	edx		; push EDX
		mov	edx,ecx		; EDX <- end of left part
		call	TextDelFrom	; delete rest of text
		pop	edx		; pop EDX
		jc	TextLeft9	; memory error
		ret

TextLeft9:	call	TextEmpty	; empty text
		stc			; set error flag
		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ší zbývající část textu za 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

		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	TextLeft6	; limit text length
		xchg	eax,ecx		; EAX <- text length

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

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

TextLeft6:	or	ecx,ecx		; check minimal text length
		js	TextLeft4	; invalid text length
		jmp	short TextLeft2	; use text length in EAX

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)

TextLeft2:	or	eax,eax		; is text empty?
		jz	TextLeft4	; text is empty
		call	TextNew		; create data buffer
		jc	TextLeft4	; 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 buffers

		add	esi,byte TEXT_Text ; ESI <- source start of text
		mov	edi,[ebx]	; EDI <- destination data buffer
		add	edi,byte TEXT_Text ; EDI <- destination 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

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

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 / TextLeft