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