News:

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

Compare two strings

Started by yvansoftware, March 30, 2010, 07:40:20 PM

Previous topic - Next topic

yvansoftware

Hi,

I'm trying to compare two strings, and I get the error "StrCmp not defined".

Here's my code:

.386
.model flat,stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\gdi32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\Comctl32.inc
include \masm32\include\comdlg32.inc
include \masm32\include\shell32.inc
include \masm32\include\oleaut32.inc
include \masm32\macros\macros.asm

includelib \masm32\lib\masm32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\Comctl32.lib
includelib \masm32\lib\comdlg32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\oleaut32.lib

.data
YvanSoftware db "(c) YvanSoftware - ALL RIGHTS RESERVED", 13 ,10 ,0
EnterYourName db "Please enter your name: ", 0
CRLF db 13,10,0
TheHolyMan db "Yvan", 0
Seriously db "Seriously? You're the MAN!", 13,10,0
LoserName db "What a loser name.", 13,10

.data?
buffer db 100 dup(?)
.code
start:
invoke StdOut,addr YvanSoftware
invoke StdOut, addr EnterYourName
invoke StdIn, addr buffer, 100
invoke StdOut, addr CRLF

invoke StrCmp,addr buffer, addr TheHolyMan
je HolyMan
IfNotHolyMan:
invoke StdOut, addr LoserName
jmp EndIfHolyMan
HolyMan:
invoke StdOut, addr Seriously
jmp EndIfHolyMan
EndIfHolyMan:

invoke ExitProcess,0
END start


What do I need to do?
(yeah, I know - it's a bullsh*t app, but it's for learning ASM ;-) )

Astro

Hi,

; preserve these registers
push esi
push edi

cld ; count downwards or from the end of the string

mov ecx,40 ; length of the string to compare
mov esi,offset FirstStr
mov edi,offset SecondStr
rep cmpsb
je @F

; not equal processing here

jmp _EXIT

@@:

; equal processing here

_EXIT:
pop edi
pop esi
ret


Best regards,
Robin.

qWord

'rep cmpsb' isn't possible :wink
.data
sz1 db "hello",0
sz2 db "hello",0
.code

cld
lea edi,sz1
mov ecx,-1
xor eax,eax
mov edx,edi
repnz scasb
sub edi,edx
mov ecx,edi
mov edi,edx

lea esi,sz2
repz cmpsb
.if ZERO?
; equal
.else
; not equal
.endif
FPU in a trice: SmplMath
It's that simple!

Astro

Huh.......???

From opcodes.chm:

QuoteCMPS - Compare String (Byte, Word or Doubleword)


Usage:  CMPS    dest,src
        CMPSB
        CMPSW
        CMPSD   (386+)

Modifies flags: AF CF OF PF SF ZF


CMPSB inc/decrements the index registers by 1

The REP prefixes can be used to process entire data items.

Best regards,
Robin.

Astro

This works, if I use repz. Maybe that is what you meant?

include \masm32\include\masm32rt.inc

.486
.model flat,stdcall

.data
    string1 BYTE "Test!",0
    string2 BYTE "Test!",0

.code

start:

    ; preserve these registers
    push esi
    push edi

    cld ; count downwards or from the end of the string

    mov ecx,6 ; length of the string to compare
    lea esi,string1
    lea edi,string2
    repz cmpsb
    je @F

    ; not equal processing here
    print "Not equal!"

    jmp _EXIT

@@:
    ; equal processing here
    print "Equal!"

_EXIT:

    pop edi
    pop esi

    ret

end start


Best regards,
Robin.

qWord

REP is not supported by cmpsX! -> see Intel's or AMD's developer guides.
FPU in a trice: SmplMath
It's that simple!

Astro

OK - but repz definitely works. Try the code!

I see why rep doesn't work - wrong op code.

REP:

QuoteF3 6C REP INS r/m8, DX Input (E)CX bytes from port DX into ES:[(E)DI]
F3 6D REP INS r/m16,DX Input (E)CX words from port DX into ES:[(E)DI]
F3 6D REP INS r/m32,DX Input (E)CX doublewords from port DX into ES:[(E)DI]
F3 A4 REP MOVS m8,m8 Move (E)CX bytes from DS:[(E)SI] to ES:[(E)DI]
F3 A5 REP MOVS m16,m16 Move (E)CX words from DS:[(E)SI] to ES:[(E)DI]
F3 A5 REP MOVS m32,m32 Move (E)CX doublewords from DS:[(E)SI] to ES:[(E)DI]
F3 6E REP OUTS DX, r/m8 Output (E)CX bytes from DS:[(E)SI] to port DX
F3 6F REP OUTS DX, r/m16 Output (E)CX words from DS:[(E)SI] to port DX
F3 6F REP OUTS DX, r/m32 Output (E)CX doublewords from DS:[(E)SI] to port DX
F3 AC REP LODS AL Load (E)CX bytes from DS:[(E)SI] to AL
F3 AD REP LODS AX Load (E)CX words from DS:[(E)SI] to AX
F3 AD REP LODS EAX Load (E)CX doublewords from DS:[(E)SI] to EAX
F3 AA REP STOS m8 Fill (E)CX bytes at ES:[(E)DI] with AL
F3 AB REP STOS m16 Fill (E)CX words at ES:[(E)DI] with AX
F3 AB REP STOS m32 Fill (E)CX doublewords at ES:[(E)DI] with EAX

REPZ:

QuoteF3 A6 REPE CMPS m8,m8 Find nonmatching bytes in ES:[(E)DI] and DS:[(E)SI]
F3 A7 REPE CMPS m16,m16 Find nonmatching words in ES:[(E)DI] and DS:[(E)SI]
F3 A7 REPE CMPS m32,m32 Find nonmatching doublewords in ES:[(E)DI] and DS:[(E)SI]
F3 AE REPE SCAS m8 Find non-AL byte starting at ES:[(E)DI]
F3 AF REPE SCAS m16 Find non-AX word starting at ES:[(E)DI]
F3 AF REPE SCAS m32 Find non-EAX doubleword starting at ES:[(E)DI]

Best regards,
Robin.

qWord

Quote from: Astro on March 30, 2010, 08:26:37 PMI see why rep doesn't work - incompatible op code.
cmpsX with a REP-prefix wouldn't make much sense - think about it  :bg

but repz definitely works. Try the code!
I've never disbelieved this - see my code

qWord
FPU in a trice: SmplMath
It's that simple!

Astro

I see!  :bg

I know I need to study the opcodes again.  :red

Best regards,
Robin.

clive

Quote from: Astro
I know I need to study the opcodes again.

Well REP and REPZ are the same opcode, so it frankly wouldn't matter at the machine code level. The inline assembler in Microsoft C (tested 12.00) is tolerant of either encoding as is MASM 5.1

-Clive
It could be a random act of randomness. Those happen a lot as well.

hutch--

I confess to not having used CMPS? since the DOS days, you can do it faster and from memory with less registers by manually incrementing the count yourself.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

jj2007

Quote from: qWord on March 30, 2010, 08:31:04 PM
Quote from: Astro on March 30, 2010, 08:26:37 PMI see why rep doesn't work - incompatible op code.
cmpsX with a REP-prefix wouldn't make much sense - think about it  :bg

Where is the problem? You need to know the length of the strings, but for example, comparing two files with identical size works just fine.

include \masm32\include\masm32rt.inc

.code
TextA db "Masm32?", 0
TextB db "Masm32!", 0

start:
mov esi, offset TextA
mov edi, offset TextB
mov ecx, SIZEOF TextA
repe cmpsb
MsgBox 0, str$(ecx), addr TextA, MB_OK
exit
end start


Quoteinclude \masm32\MasmBasic\MasmBasic.inc   ; library is here

.code
start:   xor ebx, ebx
   push Timer
   Let esi=FileRead$("\masm32\include\Windows.inc")
;   1 bytes longer, Warning Duplicate instead of WARNING Duplicate
   Let edi=FileRead$("\masm32\include\Copy_of_Windows.inc")
;   invoke lstrcmp, esi, edi            ; returns 1
;   invoke crt_strcmp, esi, edi         ; returns -1
   mov ecx, Lof("\masm32\include\Copy_of_Windows.inc")
   .if ecx>Lof("\masm32\include\Windows.inc")
      xchg ecx, eax
   .endif
   mov ebx, eax
   sub ebx, ecx
   repe cmpsb
   sub Timer, [esp]
   pop edx
   Inkey Str$("Time=%i ms", eax), Str$(", mismatch at byte EOF-%i", ecx), Str$(", diff in size=%i", ebx)
   Exit
end start

Output: Time=0 ms, mismatch at byte EOF-98, diff in size=1

qWord

jj,
rep and repz/e have the same opcode (I've not notice this before), but different termination conditions. Also in masm you can't write 'rep cmpsb'.
FPU in a trice: SmplMath
It's that simple!

jj2007

Quote from: qWord on March 30, 2010, 10:45:49 PM
jj,
rep and repz/e have the same opcode (I've not notice this before), but different termination conditions. Also in masm you can't write 'rep cmpsb'.

See attached exe from my (modified) example. It works.

qWord

when saying rep makes no sense with cmpsb, I was talking about the mnemonic 'rep', which terminates if ecx=0 - in context to cmpsX the mnemonic is named 'repz', which terminates if ecx=0 OR ZF=0. I've never said that you can't use it for comparing files or what ever...
FPU in a trice: SmplMath
It's that simple!