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