Obsah / Utility / TEXT / TextPosToOff
Zdrojový kód:
INCLUDE\UTIL\TEXT.INC, UTIL\TEXT.ASM
TextPosToOff -
Přepočet pozice znaku na bajtový offset
Funkce TextPosToOff přepočte
pozici znaku v textu (vyjádřenou ve znacích) na bajtový
offset v textu.
; -----------------------------------------------------------------------------
; Recalc character position to byte offset
; -----------------------------------------------------------------------------
; INPUT: EAX = character position (it may be out of range)
; EBX = pointer to TEXT
; OUTPUT: EAX = byte offset
; -----------------------------------------------------------------------------
|
Na vstupu funkce obsahuje registr EAX
pozici znaku v textu, registr EBX ukazatel na textovou
proměnnou. Na výstupu obsahuje registr EAX bajtový offset v
textu. Pokud ležela pozice znaku mimo platný rozsah, je
bajtový offset opraven do platných mezí. Znak mající pozici
za koncem textu bude mít offset roven délce textu (tedy
ukazující za poslední znak textu).
; ------------- Check minimal character position
TextPosToOff: or eax,eax ; check minimal character position
jle short TextPosToOff9 ; position is <= 0
.................
; ------------- Limit minimal character position
TextPosToOff9: xor eax,eax ; EAX <- 0, minimal byte offset
ret
|
Je-li pozice znaku záporná (nebo nula),
navrátí funkce ihned bajtový offset nula.
; ------------- Push registers
push ecx ; push ECX
push edx ; push EDX
push esi ; push ESI
; ------------- Prepare registers
inc eax ; EAX <- character index + 1
mov esi,[ebx] ; ESI <- data buffer
xchg eax,edx ; EDX <- required character position
mov ecx,[esi+TEXT_Length] ; ECX <- length of text
add esi,TEXT_Text ; ESI <- start of text
jecxz TextPosToOff6 ; no text
|
Text bude procházen od začátku
řetězce, aby se mohly odpočítat platné znaky. Do registru
EDX je připraven čítač pozice znaku + 1, do registru ECX
délka textu v bajtech a do registru ESI ukazatel na začátek
textu. V případě nulové délky textu bude funkce předčasně
ukončena.
; ------------- Convert position to offset
xor eax,eax ; EAX <- 0
TextPosToOff2: lodsb ; AL <- load character
cmp al,0feh ; detection bytes?
jae short TextPosToOff4 ; skip detection bytes
and al,0c0h ; mask bits
cmp al,80h ; is it first byte of character?
setne al ; AL <- 1 if it is first byte
sub edx,eax ; decrease text length
jz TextPosToOff6 ; found required position
TextPosToOff4: loop TextPosToOff2 ; next character
|
Při konverzi pozice na offset se text
prochází od začátku bajt po bajtu a je-li nalezen bajt
indikující začátek kódu znaku, sníží se čítač pozice
znaků. Po dosažení nuly pozic (nebo po dosažení konce textu)
je funkce ukončena. Za bajt začátku kódu jsou považovány
bajty s hodnotou 0 až 7Fh a 0C0h až 0FDh. Bajty 0FEh a 0FFh
jsou synchronizační, v kódu UTF-8 by se neměly vyskytovat a
jsou proto přeskakovány.
; ------------- Get character position (-> EAX)
TextPosToOff6: mov esi,[ebx] ; ESI <- data buffer
mov eax,[esi+TEXT_Length] ; EAX <- length of text
sub eax,ecx ; EAX <- byte offset
; ------------- Pop registers
pop esi ; pop ESI
pop edx ; pop EDX
pop ecx ; pop ECX
ret
|
Po nalezení požadované pozice se z
délky textu a zbylých bajtů určí bajtový offset znaku v
textu, ten je navrácen v registru EAX.
Obsah / Utility / TEXT / TextPosToOff