News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Check if signs a crosshatch

Started by ragdog, November 15, 2008, 09:44:57 PM

Previous topic - Next topic

ragdog

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

qWord

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
FPU in a trice: SmplMath
It's that simple!

KeepingRealBusy

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


fattypotato

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:

KeepingRealBusy

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.

drunk_sinsi


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

fattypotato

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

KeepingRealBusy

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.

drunk_sinsi

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.

fattypotato

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

ragdog

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++?

qWord

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
FPU in a trice: SmplMath
It's that simple!

ragdog

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


qWord

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
FPU in a trice: SmplMath
It's that simple!

ragdog

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