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
if anyone has a solution i'm all ears, thanks
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
It looks correct to me. What is wrong with it? Anyway I think the code can be reorganised and speed up.
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)
;) Is your null character smaller than '0'?
It should be something like
It is weird that you used decimal to represent ascii codes instead of hexadecimal
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
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:
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.-
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.-
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
%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
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):
Kecol.-
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.-
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.
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.-
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.-
How about:
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
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
@@:
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
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