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
; 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

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

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

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

xor eax, eax ; 0 == not ok

isHexStr endp

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

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

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

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
Posted on 2002-03-13 09:47:56 by Jens Duttke
Yes, you are right,
your version is more elegant :)

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