a friend of mine gave me some code to fix that's suppose to check each byte in a string againts a number and if it's not 0-9 for all of the bytes return -1 in eax . I rewrote things I saw wrong in his code but I still can't get it to work. here's what I have


isAllNum proc szString:DWORD
mov esi, szString
xor eax,eax
    @@:
    mov al,
    cmp al, 48 ;0
    jb @F
    cmp al, 57 ;9
    ja @F   
    lea esi, ;inc esi
    cmp al, 0
    jne @B
    jmp @good
    @@:
    mov eax,-1
    @good:
    ret
isAllNum endp


if anyone has  a solution i'm all ears, thanks
Posted on 2005-05-11 23:43:58 by Webring
It looks correct to me. What is wrong with it? Anyway I think the code can be reorganised and speed up.
Posted on 2005-05-11 23:56:50 by roticv
It always returns -1, even when the strings is blah db "1234",0 which it shouldn't because that's all numbers. should only return -1 is a non digit is in the string (e.g blah db "123g" ,0 should return -1)
Posted on 2005-05-12 00:08:36 by Webring
;) Is your null character smaller than '0'?

It should be something like


isAllNum proc szString:DWORD
mov esi, szString
xor eax, eax
    @@:
    mov al,
    test al, al
    jz @good
    cmp al, 48 ;0
    jb @F
    cmp al, 57 ;9
    ja @F   
    add esi, 1
    jmp @good
    @@:
    or eax,-1
    @good:
    ret
isAllNum endp


It is weird that you used decimal to represent ascii codes instead of hexadecimal
Posted on 2005-05-12 01:17:19 by roticv
Roticv, your code is checking one byte of the string. And if the string used is zero length, your procedure will return good instead of -1.

Webring, I think that the problem with your code is here:

lea esi, ;inc esi
cmp al, 0

You are forgetting something between this two instructions (guess what!).
Webring, you can update the roticv's code to do what you want. Roticv is right when he said that code can be improved.

Hope it help.

Kecol.-
Posted on 2005-05-12 07:06:02 by Kecol
I already *updated his code to do what I want. and if you read the code that wasn't the problem, it checks the current byte againts 0, if so then end. The code that increments the byte ptr to edi just happen to be put infront of that. That doesn't effect until it's looped

%90 of the time

@@:
mov al, ;next check,al is now updated
-----------------------------
-----------------------------
-----------------------------
lea esi, ;inc esi <---for next check
cmp al, 0 ;cmp byte currently in al, not what's been update in esi
jne @B

the code I posted in the post before this works :D
Posted on 2005-05-12 07:15:52 by Webring
Webring, you are right. I supposed that you were trying to check if next char was null. My fault (reading on the fly, sorry).
An idea: you can use ranges. Example (written on the fly):


    ; eax = byte readed
    ; you can check if eax==null here
    mov eax,   ; eax = eax - 48
    cmp al, 10
    jnc not_a_number    ; jmp is taken if al >= 10
    ; byte is a number (or null char if you did not check it before)


Kecol.-
Posted on 2005-05-12 08:06:02 by Kecol
You can't use mov for that, you should be using lea. Yea, that one of the cute code for determining whether a number is in range.
Posted on 2005-05-12 08:10:18 by roticv
I promise do not write on the fly for a while. You are right Victor, It is LEA instead of MOV.

Correct line is: LEA EAX, DWORD PTR

Just a comment. Use something like LEA ECX, DWORD PTR to maintain values (written on the fly  :D).

Kecol.-
Posted on 2005-05-12 08:37:11 by Kecol
How about:

isAllNum proc szString:DWORD
  mov esi, szString
  mov al,

@@:
  cmp al, '0'
  jc @F

  neg al
  cmp al, -'9'
  jc @F

  add esi, 1
  mov al,
  or  al, al
  jne @B
@@:
  sbb eax, eax
  ret
isAllNum endp


It uses neg to change the polarity of carry on the test for > '9' so we can elminate the final jump (replacing it with sbb).

Mirno
Posted on 2005-05-12 11:36:07 by Mirno


@@:
mov al, ;next check,al is now updated
-----------------------------
-----------------------------
-----------------------------
lea esi, ;inc esi <---for next check
cmp al, 0 ;cmp byte currently in al, not what's been update in esi
jne @B

the code I posted in the post before this works :D


The problem is that if AL contained 0, your code would NEVER reach this instruction. 0 would be considered smaller than 48 and it would exit with -1 in EAX.

If you want to return -1 for an empty string, use

cmp byte ptr,0

in the above quoted code to check if the next byte is the end of the string.

Raymond
Posted on 2005-05-12 11:53:31 by Raymond
i prefer .if .while ... instructions. its more easier to read..

IsNumber proc uses esi _string:dword
mov esi,_string
.while byte ptr!=0
lodsb
.if al<"0" || al>"9"
xor eax,eax
dec eax
ret
.endif
.endw
xor eax,eax
inc eax
ret
IsNumber endp
Posted on 2005-05-12 14:04:51 by diablo2oo2