Hi
I have a little question to make a check for a string
check in string all 3,6,9,12,..... counter if a (#)
if 3 signs a (#) if correct, if 6 signs a (#) if correct,....
here is my trying routine this works not
szTest db "AB#CD#EF#GH#IJ",0;....
IfCorrectFormat proc i_buff:DWORD
mov edi,[i_buff]
mov ebx,0
@Loop:
inc edi
inc ebx
test ebx,3
jnz @Loop
mov al, byte ptr [edi]
cmp byte ptr [edi],0 ;compare if edi 0
je @Out ;if 0 jump out
cmp al,"#"
jne @Loop
invoke MessageBox,0,0,0,MB_OK
jmp @Loop
@Out:
ret
IfCorrectFormat endp
Have your an idea to implement it?
Greets and thanks in forward
hi,
Is this what you ask for:
; return: TRUE or FALSE
IsCorrectFormat proc uses ebx edi esi lpBuffer:DWORD
mov edx,lpBuffer
movzx eax,BYTE ptr [edx]
xor ecx,ecx
xor ebx,ebx
mov edi,1
xor esi,esi
jmp @w
;align 16
@@: lea edx,[edx+1]
movzx eax,BYTE ptr [edx]
xor ebx,ebx
@w: test eax,eax
jz @F
mov eax,-1
cmp ecx,2
cmovl ebx,edi
cmove ecx,eax
cmp eax,023h ;"#"
cmove esi,edi
lea ebx,[ebx+esi]
cmp ebx,2
lea ecx,[ecx+1]
jne @B
xor eax,eax
ret
@@:
mov edx,1
xor eax,eax
cmp ecx,2
cmove eax,edx
ret
IsCorrectFormat endp
example:
"AB" -> TRUE
"AB#CD" -TRUE
"AB#" -> FALSE
"AB#CD#EF" -> TRUE
"#AB" -> FALSE
"A#CD"-> FALSE
"AB#C'"-> FALSE
""-> FALSE
regards, qWord
How about:
; return: TRUE or FALSE
IsCorrectFormat proc uses esi lpBuffer:DWORD
mov esi,lpBuffer
Next:
lodsw
cmp ah,0
jz Good
cmp ah.'#'
jz Bad
cmp al,0
jz Bad
cmp al.'#'
jz Bad
lodsb
cmp al,0
jz Good
cmp al.'#'
jz Next
Bad:
mov eax,FALSE
jmp Exit
Good:
mov eax,TRUE
Exit:
ret
IsCorrectFormat endp
maybe?
xor edi, edi
xor ecx, ecx
mov ecx, LENGTHOF szTest
mov edi, offset szTest
do_ck:
mov al, byte ptr[edi]
cmp al, '#'
jz msg
inc edi
loop do_ck
msg:
send msg.....or something
done:
Fatty,
I don't think so. The first and second characters need to be checked for not '#', and both need to be present, not just the first, and the third character must be '#' or null. In addition, your LENGTHOF will scan every character of the string without verifying anything but the terminator - it does eliminate the checks for null. Also, doesn't LENGTHOF return the declared size of the string buffer and not the length of the filled in portion of the buffer to the null terminator?
Dave.
;returns EAX=0 if no error i.e. string is correct
;assumes a string format of "<don't care><don't care><# or terminating 00>"
IfCorrectFormat proc i_buff:DWORD
mov edx,i_buff
mov ecx,2
next: movzx eax,byte ptr [ecx+edx]
test eax,eax
jz done
cmp al,"#"
jnz nope
add ecx,3
jmp next
nope: mov al,1
done: ret
IfCorrectFormat endp
What's the format of the string? If it could be "AB#C" (terminating null not at position 3/6/9...) you will need to check each byte.
Every 3 bytes is a horrible alignment - can you change the source string's format?
Oh sorry Dave, maybe this?
.data
szTest db "AB#CD#EF#GH#IJ",0
.code ; Tell MASM where the code starts
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start: ; The CODE entry point to the program
xor edi, edi
xor ecx, ecx
mov ecx, LENGTHOF szTest ; returns bytes in szTest, including terminate
mov edi, offset szTest
do_ck:
mov al, byte ptr[edi]
cmp al, '#'
jnz no_hash
nop ;;; only here when al = '#'
nop ;;; print msg or whatever here
nop
no_hash:
nop ;;; print other chars here if you want?
nop
nop
inc edi
loop do_ck
exit
drunk_sinsi,
You cannot just skip the second character, nor can you not check the third character for the '#'. You also have to check for null at the correct point (either the first character of the set, or following the second character of the set. If you just add 3 to the pointer without checking for the null somewhere before that, then you can walk into a memory fault.
I do not try to change the requirements of the defined input, I just code the tests to check for the stated requirements.
fattypotato,
Your post came in while I was composing my answer above. Point 1 as before, LENGTHOF checks the length of the array, you need to check for a trailing null, don't assume that a string completely fills an array. Point 2, the original post specified that the string format was to be checked, 2 characters, a '#' separator, 2 characers, a null following the second character of a set (the '#' only between two sets of two characters). At least that is what I see in the example given.
Dave.
Quote from: KeepingRealBusy on November 16, 2008, 05:27:10 AM
You cannot just skip the second character, nor can you not check the third character for the '#'. You also have to check for null at the correct point (either the first character of the set, or following the second character of the set. If you just add 3 to the pointer without checking for the null somewhere before that, then you can walk into a memory fault.
;assumes a string format of "<don't care><don't care><# or terminating 00>"
The string might be in a random format or it might be in a rigid format...
Quote from: KeepingRealBusy on November 16, 2008, 05:27:10 AM
I do not try to change the requirements of the defined input, I just code the tests to check for the stated requirements.
szTest db "AB#CD#EF#GH#IJ",0;....
So do I.
Sometimes I just don't get it, you're right Dave.
All right, I gotta get out of here! When the big boys look in here and see what we've been up to we're all gonna get SPANKED!
Well maybe just me :bg
Hi Thanks to all for your time and help
I must test all your routine i have only tested from drunk_sinsi
This works :U
@drunk_sinsi
Quote
What's the format of the string? If it could be "AB#C" (terminating null not at position 3/6/9...) you will need to check each byte.
Every 3 bytes is a horrible alignment - can you change the source string's format?
No i cannot change the string format.
i have try yesterday @ a late time with this
.data
s3 dw 3
@Loop:
inc ebx
mov eax,ebx ; move counter ebx in eax
xor edx,edx ; before divide delete edx!
div s3 ; eax=eax/word (s3=3), rest in edx !
or edx,edx
jnz @F
invoke MessageBox,0,0,0,MB_OK
@@:
jmp @Loop
I think i must inc a counter if the counter divide with 3 then check if the 3te,6,9,12..... signs a (#)
Greets and Thanks
Ragdog
Ps: what is cmovl & cmove if this from c++?
Quote from: ragdog on November 16, 2008, 10:19:52 AM
Ps: what is cmovl & cmove if this from c++?
cmove and cmovl are instructions - it has nothing to do with c++
cmove: conditional move if equal
cmovl: conditional move if less
regards, qWord
Thanks qWord
i have tested you routine this works not correct
Have i change my string to szTest db "12+34#56#78#90",0 ;wrong format
if the return code true.
With drunk_sinsi routine have i the right result this works fine
thank you for your work and help
ok - what is about this:
"12+34#56#78#90" -> TRUE
"12+34+56-78#90" -> TRUE
"-12+43" -> FALSE (???)
; return: TRUE or FALSE
IsCorrectFormat proc uses ebx edi esi lpBuffer:DWORD
mov edx,lpBuffer
movzx eax,BYTE ptr [edx]
xor ecx,ecx
xor ebx,ebx
mov edi,1
xor esi,esi
jmp @w
;align 16
@@: lea edx,[edx+1]
movzx eax,BYTE ptr [edx]
xor ebx,ebx
@w: test eax,eax
jz @F
mov eax,-1
cmp ecx,2
cmovl ebx,edi
cmove ecx,eax
cmp eax,023h ;'#'
cmove esi,edi
cmp eax,02bh ;'+'
cmove esi,edi
cmp eax,02dh ;'-'
cmove esi,edi
lea ebx,[ebx+esi]
cmp ebx,2
lea ecx,[ecx+1]
jne @B
xor eax,eax
ret
@@:
mov edx,1
xor eax,eax
cmp ecx,2
cmove eax,edx
ret
IsCorrectFormat endp
Test drunk_sinsi routine
I mean this
AB-CD#EF#.. false
AB#CD#EF#.. TRUE this format is only true
AB#CD,EF, false
AB'CD'EF.. false
All 3,6,9,12,15.. sings must be a (#) then if true
ragdog,
One question about the validity of the two characters. As displayed, you have AB CD EF ... Does this mean that the characters must be AB CD EF, or just alphabetic, or upper case alphabetic, or just any character? If they can be any character, can they be '#"?
Dave.
This AB CD EF is a any character is relativ
I can also make 12 34 56 75...
This problem is only the separator (#) this must be in 3,6,9,12 .......... signs of the string
If it could be any character, then #b#c#### would also be valid (split into #b# c## and ##, the first and second character any character, the third character '#' or null).
Quote from: ragdog on November 16, 2008, 01:50:36 PM
This AB CD EF is a any character is relativ
I can also make 12 34 56 75...
This problem is only the separator (#) this must be in 3,6,9,12 .......... signs of the string
so, the last character in string can also be a crosshatch ?
if so, my routine does the job:
; return: TRUE or FALSE
IsCorrectFormat proc uses ebx edi esi lpBuffer:DWORD
mov edx,lpBuffer
movzx eax,BYTE ptr [edx]
cmp eax,023h ; position 1 not allowed for a crosshatch
je @False ;
xor ecx,ecx
xor ebx,ebx
mov edi,1
xor esi,esi
jmp @w
;align 16
@@: lea edx,[edx+1]
movzx eax,BYTE ptr [edx]
xor ebx,ebx
@w: test eax,eax
jz @F
mov eax,-1
cmp ecx,2
cmovl ebx,edi
cmove ecx,eax
cmp eax,023h ;'#'
cmove esi,edi
lea ebx,[ebx+esi]
cmp ebx,2
lea ecx,[ecx+1]
jne @B
@False:
xor eax,eax
ret
@@:
mov edx,1 ; if the last char. is a crosshatch or termination-zero -> TRUE
xor eax,eax ; else -> FALSE
cmp ecx,2 ;
cmove eax,edx ;
cmp ecx,0 ;
cmove eax,edx ;
ret
IsCorrectFormat endp
Quoteso, the last character in string can also be a crosshatch ?
No only the 3,6,9,12....... is a # in the string not the last
AB#CD#EF#GH#IJ#KL#NO# ............................
3 6 9 12 15 18 21 24................................
This AB CD.... is relative Char
ragdog,
confirm or correct the following assumptions:
- a crosshatch is a separator
- a "separator" separates two expressions
- a expression is two bytes long and can consist of any character except the separator
- if there is only one expression in your string,no separator is needed
- if there are two expressions in your string, only one separator is needed
- if there are N expressions, you need N-1 separators
- so a separator can not be the first or the last character in string
:bg
This is correct
- a crosshatch is a separator
- a "separator" separates two expression
- a expression is two bytes long and can consist of any character except the separator
- so a separator can not be the first or the last character in string
Correct format is:
AB
AB#CD
AB#CD#EF
AB#CD#EF#GH
...
...
.
wrong Format is
#CD
A#BC
...
..
The 3te,6,9,12 .... must be a (#) separator
ragdog,
AFAIKs, that's exactly what the routine from my first post does :P
regards qWord
No
this is a wrong format AB-CD#EF. by you routine is correct.
Try from drunk_sinsi routine this works correct
your right - sorry
i confused my self with all these conditional mov's :bg
her is my corrected version (i hope so :bg)
; return: TRUE or FALSE
IsCorrectFormat proc uses ebx edi esi lpBuffer:DWORD
mov edx,lpBuffer
movzx eax,BYTE ptr [edx]
xor ecx,ecx
xor ebx,ebx
mov edi,1
jmp @w
;align 16
@@: lea edx,[edx+1]
xor ebx,ebx
movzx eax,BYTE ptr [edx]
@w: test eax,eax
jz @F
mov esi,-1
cmp ecx,2
cmove ebx,edi
cmove ecx,esi
xor esi,esi
cmp eax,023h ;"#"
cmove esi,edi
lea ebx,[ebx+esi]
cmp ebx,1
lea ecx,[ecx+1]
jne @B
xor eax,eax
ret
@@:
mov edx,1
xor eax,eax
cmp ecx,2
cmove eax,edx
ret
IsCorrectFormat endp
regards, qWord
EDIT: I've optimize it a bit