here is a little routine to check if
a string is a hex string till a delimiter.
I did it to prevent incorrect results with
the masm32 lib funtion htodw.

Kinda old school style, this one.



; -- -------------------------------------------------------------------------
; Procedure: isHexStr
;
; USAGE:
; invoke isHexStr, ADDR tstr, ln
;
; The procedure terminates if a delimiter <SPACE>,<TAG>,CR,LF or 0 is found.
; NOTE: the source string will be modified with a terminator if the test string
; was terminated by a delimiter except 0. String is ready to use with the
; htodw masmLib funtion.
;
; IN:
; tstr: String address
; ln: length of the string
;
; OUT: eax
; 1 = ok
; 0 = not ok
;

isHexStr proc uses esi edi tstr:DWORD, ln:DWORD

mov esi, tstr
mov edi, esi
add edi, ln

@@looper:
mov al, [esi]

cmp al, 32
je @@xend
cmp al, 9
je @@xend
cmp al, 0dh
je @@xend
cmp al, 0ah
je @@xend
test al,al
je @@xend

cmp al, '0'
jl @@nothex
cmp al, '9'
jle @@adv
and al, 0DFh ; set to uppercase
cmp al, 'A'
jb @@nothex
cmp al, 'F'
ja @@nothex

@@adv:
inc esi
cmp esi, edi ; end of buffer reached ?
jb @@looper

@@xend:
cmp esi, tstr ; any proceeded
je @@nothex ; == means not
mov byte ptr [esi], 0 ; set terminator
mov eax, 1 ; set ok
ret

@@nothex:
xor eax, eax ; 0 == not ok
ret

isHexStr endp

Posted on 2002-03-11 14:26:05 by marsface
hi!

That's a nice idea, but i would recommend to use something like a lookup table, to check if the char is allowed or not.
This would save you the many compares and jumps, and would improve the speed extremly.

-----

Before some week's I've written a h2dw algorithm, which is faster than the current one, which is included in the masm package ... it may has an "unsual" design, but it works quite good.



htodw proc lpString:DWORD

;----------------------------------------
; Convert hex string into dword value
; return value in eax
;----------------------------------------
; Written by Jens Duttke
;----------------------------------------

mov edx, lpString
xor eax, eax

again:
mov cl, [edx]
test cl, cl
jz done
inc edx

test cl, 1000000b ; Char is a letter ?
jnz @F ; If Char is not a letter Then
sub cl, 48 ; set the base of '0' to 0

shl eax, 4 ; Write the nibble in eax
or al, cl

jmp again
@@:
and cl, 0011111b ; Remove the left 2 bits (left bit set = char is a letter; right bit set = small letter)
add cl, 9 ; set the base of 'A' to 10 ('A' = 1; 1 + 9 = 10)

shl eax, 4 ; Write the nibble in eax
or al, cl

jmp again
done:

ret
htodw endp


I've also modified the routine to work with qword hex-strings. Since it's maybe a bit too much code, to post it here I've attached both, the htodw and the htoqw as sources to this post.

Cu, Jens Duttke
----
http://www.emucheater.com
http://cyberpad.psxemu.com
Posted on 2002-03-13 09:47:56 by Jens Duttke
Yes, you are right,
your version is more elegant :)

Thnx!
Posted on 2002-03-14 00:03:15 by marsface