News:

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

String comparing issue

Started by Nilrem, April 18, 2005, 08:38:37 AM

Previous topic - Next topic

Nilrem

I'm trying to optimize my code (so getting rid of apis). I have a drop down menu and when I press a button it detects what has been selected.
This works perfectly fine with lstrcmp, offset lpDropDown, offset string
.if eax==0
code
.endif
code

I saw some other code lying around

mov      esi, offset string1
      mov      edi, offset string2
@@:
      mov      al,[esi]
      cmpsb
      jne      strings_not_equal
      test      al, al
      jne        @b
strings_are_equal:
      .....
strings_not_equal:
      .....
however this will not work because one of the strings, lpDropdown is not null terminated (well I don't think it is because I don't actually define it myself).
I then saw this for strings that aren't null terminated:
mov      esi, offset string1
      mov      edi, offset string2
      mov      ecx,string_length
      repz     cmpsb
      jne      strings_not_equal
strings_are_equal:
      .....
strings_not_equal:
      .....

however this doesn't work either, I think it is because one of the strings actually is null terminated. Though now looking at it in detail I think it is because only one string is a dword. I cannot change this though as one of them has to be declared as a byte otherwise I get an error compiling.
Thanks. I'm still learning I know but I want to stop relying on apis so much and optimize my code.

thomasantony

Hi,
   AFAIK, you don't need to do mov al,[esi] if you are using cmpsb. I think

   mov al,[esi]
   cmp al,[edi]
   jne @blah

is faster than cmpsb. Then don't do test al,al. Instead, put length of one string in ecx and do

dec ecx
jnz @B   ; if more than 0 jump


Thomas
:U
There are 10 types of people in the world. Those who understand binary and those who don't.


Programmer's Directory. Submit for free

Nilrem


mov      eax, offset String21
      mov      edi, offset lpDropDown
      mov      ecx,7
      @@:
      cmp al, [edi]
      dec ecx
jnz @B   ; if more than 0 jump
      jne      @f

This isn't right obviously because it only compares the first byte. Could I use cmp al, [edi+ecx] or something to that effect?

thomasantony

Oops,
    My mistake :red . You either do cmp al,[edi+ecx] or do an inc edi before the dec ecx

Thomas :U
There are 10 types of people in the world. Those who understand binary and those who don't.


Programmer's Directory. Submit for free

Nilrem

Doesn't work.
mov      eax, offset String21
      mov      edi, offset lpDropDown
      mov      ecx,7
      @@:
      cmp byte ptr al, [edi]
      jne      @f
      inc edi ; byte position
      inc eax ; byte position
      dec ecx ; counter
jnz @B   ; if more than 0 jump


For some reason when comparing the first byte al is 2A (which is an *) and edi is 4A which is J (what it should be). However both of the strings are the same. I did this in olly command bar
? al
and it showed this *J
did the same in edi and it had something like %\J
I'm not sure why this is happening or how to prevent it?

hutch--

Nilrem,

You only have 2 choices with astring compares with ANSI characters, either use TWO zero terminated strings to compare or set a length for the comparison and pass it to the procedure that does the comparison. Let us know what you have in mind and it can probably be fixed up easily enough.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Nilrem

String21   db 'JongBot',0
that is one of the strings

However the other string is not declared it is just whatever is selected in the dropdownmenu (lpDropDown).
So I think that isn't zero terminated.
Thanks Hutch and Thomas for giving help. So that is what, the second option you said Hutch. 8-)

thomasantony

Hi,
  If you get the string from a dropdown menu, it will be a zero terminated string

Thomas :U
There are 10 types of people in the world. Those who understand binary and those who don't.


Programmer's Directory. Submit for free

Nilrem

Ok I wonder why the code is not working then if they are both zero terminated (and of course it is since don't all windows api results end with a zero terminated string?).

thomasantony

Why not use the szCmpi or szCmp functions in the MASM32 library?

Thomas :U
There are 10 types of people in the world. Those who understand binary and those who don't.


Programmer's Directory. Submit for free

hutch--

Here is an algo to do sring compares based on a preset length.

LATER : Tweaked  :toothy


; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

strcmp proc str1:DWORD,str2:DWORD,cnt:DWORD

    push ebx
    push esi

    mov esi, str1       ; load 1st byte data in ESI
    mov edx, str2       ; load 2nd byte data in EDI
    mov eax, cnt        ; load byte count in EAX
    add esi, eax        ; add byte count to ESI
    add edx, eax        ; add byte count to EDI
    neg eax             ; reverse sign in EAX
    xor ebx, ebx        ; clear EBX to prevent stall with BL

  @@:
    mov bl, [esi+eax]   ; load byte at ESI into BL
    cmp bl, [edx+eax]   ; compare BL to byte in EDI
    jne @F              ; exit if not equal
    add eax, 1          ; add 1 to test next pair of bytes
    jnz @B              ; jump back if count is not zero

    mov eax, -1         ; non zero is matching strings
    jmp quit

  @@:
    xor eax, eax        ; zero is non matching strings

  quit:
    pop esi
    pop ebx

    ret

strcmp endp

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Nilrem

Haven't tested it yet. Some questions however. Why would bl stall? Why add eax,1 isn't inc eax quicker, or is that just preference?
Secondly since this post is about trying to optimize my code, I have several strings to compare, therefore how could I manipulate this easier, apart from putting strings into strings (for example string1 is always compared so move the next string, string2 into string1 using repnz or whatever it was I forgot) I'm asking this because I'm contemplating about a swicth statement but am unsure how to go about it. Thanks a lot in helping I really do appreciate it, maybe I am annoying but I really want to be a more efficient programmer. 8-)


Edit
Nevermind I see it's a procedure ready to use easily. However the questions still remain concerning efficieny and switch statements.
Basically I want to compare two strings (obviously) and then do something. At the moment I have the rather inefficient:


invoke lstrcmp, str1, str2 //str1 been dropdownmenu
.if eax==0
  code
.endif
invoke lstrcmp, str1, str2
.if eax==0
  code
.endif
invoke lstrcmp, str1, str2
.if eax==0
  code
.endif
You get the idea...


Edit again
I know you can't do this in asm, but I just remembered a project in Excel where using a V-lookup was incredibly useful, if that could be used that would be great. Just trying to prove I don't ask reams of questions without putting the effort in. 8-)

AeroASM

inc and dec are slower on the P4 compared to add and sub. (I think)

lingo

#13
the same but shorter  :lol

strcmp proc str1:DWORD,str2:DWORD,cnt:DWORD
    push   esi
    mov    esi, str1   ; load 1st byte data in ESI
    mov    edx, str2   ; load 2nd byte data in EDI
    mov    eax, cnt    ; load byte count in EAX
LoopA:
    add    eax,-1
     jl    quit     
    movzx  ecx, byte ptr [esi+eax]   ; load byte at ESI into BL
    cmp    cl, [edx+eax]              ; compare BL to byte in EDI
     je    LoopA
    xor    eax, eax                   ; zero is non matching strings
quit:
    pop    esi
    ret
strcmp endp


Regards,
Lingo

Nilrem

Thankyou. 8-) Had problems getting it to work. Hutch yours worked perfectly.