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

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