Discussion:
repe cmpsb instruction
(too old to reply)
Alex
2004-08-30 04:26:45 UTC
Permalink
Hi guys

strange problem here..

here is the scenario, I am trying to compare two strings, my routine
is searching thru the root directory of a floppydisk to find a filename.

string1 db 'KERNEL32SYS' ;same format of name in root dir table

I have ds:esi pointing to string1 and es:edi and pointing to a buffer which
contains the string I am comparing against (string is always 11 characters
long)
(8 charfilename+3byte ext), i find i have to set ecx to 12 for it to check
the whole
string (using repe cmpsb). If i set it to 11, it seems to miss checking the
last character.
I cant understand why though? shouldnt mov ecx,11 be alright?

Alex.
The Wannabee @
2004-08-30 09:48:58 UTC
Permalink
Alex..
alex
2004-08-30 11:58:58 UTC
Permalink
thats the best answer i have had so far.. well done
Alex..
Herbert Kleebauer
2004-08-30 15:26:50 UTC
Permalink
Post by alex
thats the best answer i have had so far.. well done
If you post your code, you certainly will get a longer
answer.
Betov
2004-08-30 15:37:41 UTC
Permalink
Post by Herbert Kleebauer
Post by alex
thats the best answer i have had so far.. well done
If you post your code, you certainly will get a longer
answer.
Or... If he re-reads his code, he will probably no more
have a question to ask...

Though, Alex, you should also check the trailing Zero
(or whatever ending Char) to save you from taking
"NameA" as a valid "Name"...).

Betov.


< http://betov.free.fr/RosAsm.html >
luvr
2004-08-30 22:17:45 UTC
Permalink
Post by Betov
Though, Alex, you should also check the trailing Zero
(or whatever ending Char) to save you from taking
"NameA" as a valid "Name"...).
Errr... Rene? Sorry to disappoint you, but he _was_ talking about
comparing file names as stored in DOS diskette directory entries; just to
put the record straight, such strings are fixed-size, 11-byte strings, not
terminated by any special character, but simply by their fixed, 11-byte
length.

--Luc.
Octavio
2004-08-30 19:23:33 UTC
Permalink
Post by Alex
Hi guys
I cant understand why though?
debug your program and you will understand
Post by Alex
shouldnt mov ecx,11 be alright?
yes, but it seems that the program has some bugs.
alex
2004-08-31 01:34:33 UTC
Permalink
ok.. seeing how everyone is flaming me and telling me to post code, debug
etc

I decided to write a simple dos program in asm that does _EXACLY_ the
same sort of thing my other program does.. and I have the same problem.

The end result of this program is that the string matches! which is crap
because
they do _NOT_

yet again, if I set ecx to 12, the code functions normally. Can anyone see
what
I am doing wrong in my use of repe cmpsb ?

and YES i have stepped through it with a debugger. It seems logical that ecx
should be
set at 11 for this to work... but it doesnt.

I am using nasm.
;------------------------------------

org 0x100

start:
mov ax,cs
mov ds,ax
mov es,ax
mov esi,string1
mov edi,string2
mov ecx,000bh
repe cmpsb
mov eax,0900h
cmp ecx,0000h
je s_ok
mov edx,dosmsg2
int 21h
jmp bail
s_ok: mov edx,dosmsg1
int 21h
bail: mov eax,4c00h
int 21h

string1 db 'KERNEL32SYS' ;fixed length strings
string2 db 'KERNEL32SYN'
dosmsg1 db 'Strings match.',0dh,0ah,'$'
dosmsg2 db 'Strings do NOT match.',0dh,0ah,'$'
The Wannabee @
2004-08-31 01:47:21 UTC
Permalink
Post by alex
ok.. seeing how everyone is flaming me and telling me to post code, debug
etc
I decided to write a simple dos program in asm that does _EXACLY_ the
same sort of thing my other program does.. and I have the same problem.
The end result of this program is that the string matches! which is crap
because
they do _NOT_
yet again, if I set ecx to 12, the code functions normally. Can anyone see
what
I am doing wrong in my use of repe cmpsb ?
and YES i have stepped through it with a debugger. It seems logical that ecx
should be
set at 11 for this to work... but it doesnt.
I am using nasm.
;------------------------------------
Hello, the reason for the error is that repe cmpsb set the zero flag if it
succeed, and you forgot to test it. ECX is decreased, even if the
operation fails. So ecx will be 0, even when cmpsb fails on the last char.
Post by alex
org 0x100
mov ax,cs
mov ds,ax
mov es,ax
mov esi,string1
mov edi,string2
mov ecx,000bh
repe cmpsb
mov eax,0900h
cmp ecx,0000h
je s_ok
mov edx,dosmsg2
int 21h
jmp bail
s_ok: mov edx,dosmsg1
int 21h
bail: mov eax,4c00h
int 21h
string1 db 'KERNEL32SYS' ;fixed length strings
string2 db 'KERNEL32SYN'
dosmsg1 db 'Strings match.',0dh,0ah,'$'
dosmsg2 db 'Strings do NOT match.',0dh,0ah,'$'
The Wannabee @
2004-08-31 01:54:53 UTC
Permalink
På Tue, 31 Aug 2004 03:47:21 +0200, skrev The Wannabee
Post by The Wannabee @
Hello, the reason for the error is that repe cmpsb set the zero flag if
it succeed, and you forgot to test it. ECX is decreased, even if the
operation fails. So ecx will be 0, even when cmpsb fails on the last char.
A bit confusingly written, but point is, before you test ecx, the zero
flag has been cleared allready to indicate failure, and when you test ecx
for zero, you overwrite the status of the flag. And ECX will be 0 at this
point, in any case.


CMPSB
Compare Strings


CMPSB ; A6 [8086]
CMPSW ; o16 A7 [8086]
CMPSD ; o32 A7 [386]

CMPSB compares the byte at [DS:SI] or [DS:ESI] with the byte at [ES:DI] or
[ES:EDI], and sets the flags accordingly. It then increments or decrements
(depending on the direction flag: increments if the flag is clear,
decrements if it is set) SI and DI (or ESI and EDI).

The registers used are SI and DI if the address size is 16 bits, and ESI
and EDI if it is 32 bits. If you need to use an address size not equal to
the current BITS setting, you can use an explicit a16 or a32 prefix.

The segment register used to load from [SI] or [ESI] can be overridden by
using a segment register name as a prefix (for example, ES CMPSB). The use
of ES for the load from [DI] or [EDI] cannot be overridden.

CMPSW and CMPSD work in the same way, but they compare a word or a
doubleword instead of a byte, and increment or decrement the addressing
registers by 2 or 4 instead of 1.

The REPE and REPNE prefixes (equivalently, REPZ and REPNZ) may be used to
repeat the instruction up to CX (or ECX - again, the address size chooses
which) times until the first unequal or equal byte is found.
alex
2004-08-31 02:10:07 UTC
Permalink
Thank you!!

Looks like you're absolutely correct here :)
I completely overlooked this!

So I could simply use a jz or jnz instruction after this
to make the descision on what action to take I guess.

Thank you for taking the time to reply
appreciate it :)

Regards
Alex
Post by The Wannabee @
På Tue, 31 Aug 2004 03:47:21 +0200, skrev The Wannabee
Post by The Wannabee @
Hello, the reason for the error is that repe cmpsb set the zero flag if
it succeed, and you forgot to test it. ECX is decreased, even if the
operation fails. So ecx will be 0, even when cmpsb fails on the last char.
A bit confusingly written, but point is, before you test ecx, the zero
flag has been cleared allready to indicate failure, and when you test ecx
for zero, you overwrite the status of the flag. And ECX will be 0 at this
point, in any case.
CMPSB
Compare Strings
CMPSB ; A6 [8086]
CMPSW ; o16 A7 [8086]
CMPSD ; o32 A7 [386]
CMPSB compares the byte at [DS:SI] or [DS:ESI] with the byte at [ES:DI] or
[ES:EDI], and sets the flags accordingly. It then increments or decrements
(depending on the direction flag: increments if the flag is clear,
decrements if it is set) SI and DI (or ESI and EDI).
The registers used are SI and DI if the address size is 16 bits, and ESI
and EDI if it is 32 bits. If you need to use an address size not equal to
the current BITS setting, you can use an explicit a16 or a32 prefix.
The segment register used to load from [SI] or [ESI] can be overridden by
using a segment register name as a prefix (for example, ES CMPSB). The use
of ES for the load from [DI] or [EDI] cannot be overridden.
CMPSW and CMPSD work in the same way, but they compare a word or a
doubleword instead of a byte, and increment or decrement the addressing
registers by 2 or 4 instead of 1.
The REPE and REPNE prefixes (equivalently, REPZ and REPNZ) may be used to
repeat the instruction up to CX (or ECX - again, the address size chooses
which) times until the first unequal or equal byte is found.
Loading...