Hello,

I just need an instr-function like I know in Basic and other high-level programming languages. I tried to build it on my own, but it seems I'm not able to find the error - the procedure returns 0, anyway.

Perhaps, anyone will be able to find my error, it would be really great :) .

My concept is to find the first match of the first character of the substring at first. If I have found one, I just check wheter the following characters match, too, otherwise go on searching the next match of the first character.

InstrEx			PROC    StartPos:DWORD, String:DWORD, SubString:DWORD


mov eax, String
dec eax
dec eax
add eax, StartPos

;find first match of the first char
FindFirst:

inc eax
mov ebx, [eax]
mov ecx, SubString
mov ecx, [ecx]

cmp ebx, ecx
je FoundFirst

cmp ebx, 0
je NotFound

jmp FindFirst

FoundFirst: push eax
mov ecx, SubString
dec ecx
push ecx

CompareLoop: pop ecx
inc ecx
mov ebx, [eax]
push ecx
mov ecx, [ecx]

cmp ecx, 0
je Found

cmp ecx, ebx
je CompareLoop

FalseFirst:
pop eax
jmp FindFirst

Found: pop eax
sub eax, String
jmp Done

NotFound: mov eax, 0

Done: ret
InstrEx ENDP


Thanks to everybody who just reads this message or even tries to help me, and I'd love to have some nice answers ( ;) )

yours,
Claus
Posted on 2004-06-23 10:49:10 by ndn4u
Oh,

well, the code doesn't look very well, it seems I used sometimes tabs, sometimes just spaces. In my editor, it looks really fine ...
Posted on 2004-06-23 10:50:54 by ndn4u
MASM32 package has a MASM32.lib with a InString procedure with source. For some working code you can look at.

Regards, P1 :cool:
Posted on 2004-06-23 12:50:25 by Pone
would still be nice to fix the source problem though - people will learn from that. I'm too tired to have a look at the source right now though :)
Posted on 2004-06-23 17:05:17 by f0dder
This *seems* to work, from your original algo with some changes, you were not popping ecx in case of a not found and messing up the stack, as well as fixing up a few logic problems. I haven't thoroughly tested it but it should be pretty close to OK.

InstrEx		FRAME    StartPos, String, SubString


mov eax, [String]
dec eax
add eax, [StartPos]
mov ecx, [SubString]


;find first match of the first char
FindFirst: inc eax
mov bl, [eax]

mov dl, [ecx]

cmp bl, dl
je >FoundFirst

cmp bl, 0
je >NotFound

jmp FindFirst

FoundFirst: push eax
dec ecx
dec eax

CompareLoop: inc ecx
inc eax
mov bl, [eax]
mov dl, [ecx]

cmp dl, 0
je >Found

cmp dl, bl
je CompareLoop

FalseFirst: pop eax
mov ecx, [SubString]
jmp FindFirst

Found: pop eax
sub eax, [String]
jmp >Done

NotFound: mov eax, 0

Done: ret
ENDF
Posted on 2004-06-23 17:45:57 by donkey
Hello,

thanks for your help, especially to donkey, it is really fine for a beginner like me.
I will have a look at the InString-Function in the Masm32-Library, but I'd like to finish my own version, just for learning.


The code of donkey seems to be problematic:

First, I didn't know a FRAME yet, and I didn't get it working. Is it like a PROC or like a MACRO? How can I use it?
So, I couldn't test the source, but I have some questions nevertheless:
1) mov eax, (line 3) : Why do you use [] ? I think I have to use the memory address, so that I can increment or decrement it. By now, I think the first character is incremented or decremented! The same with line 5 and 6.

2) Why do you always put a > after jumping-instructions? My Masm32 says this is an error?

Of course, my greatest problem was that I just compared 4 bytes each time instead of only one byte.
I hope you can answer my (perhaps stupid) questions. And thank you another time for the replies.

Regards,
Claus
Posted on 2004-06-24 09:16:01 by ndn4u
Well donkey uses goasm and not masm, so his code will look un-masmish. FRAME is like proc in masm if I am not wrong. I leave it for donkey to explain the rest.
Posted on 2004-06-24 09:39:41 by roticv
Hello,

OK, but with donkey's help, I was able to get my version running:


InstrEx PROC StartPos:DWORD, String:DWORD, SubString:DWORD

mov eax, String
dec eax
dec eax
add eax, StartPos

;find first match of the first char
FindFirst:

inc eax
mov dl, [eax]
mov ecx, SubString
mov dh, [ecx]

cmp dl, dh
je FoundFirst

cmp dl, 0
je NotFound

jmp FindFirst

FoundFirst:
push eax
mov ecx, SubString
dec ecx
dec eax

CompareLoop: inc ecx
inc eax
mov dl, [eax]
mov dh, [ecx]

cmp dh, 0
je Found

cmp dh, dl
je CompareLoop

FalseFirst:
pop eax
jmp FindFirst

Found: pop eax
sub eax, String
jmp Done

NotFound: mov eax, 0

Done: ret
InstrEx ENDP


Now, I will have to test the performance of my code and the masm32-included code, but I think I won't have a chance.

Regards,
Claus
Posted on 2004-06-24 09:48:17 by ndn4u
Claus von der Burchard,

The other 2 questions you posted are also GoAsm syntax related. The [] is "Proper Intel" syntax, (correct me if I'm wrong), I think NASM also uses it, MASM discards these for 'ease of use'. And the < > lines in the jumps are like MASM @B and @F.

Regards
Posted on 2004-06-25 01:52:10 by SubEvil
Claus,

Scanner style string searches all have more or less the same logic unless you want to try out some of the exotic ones. You scan the source for the first character in the string you are trying to find, when you find it you branch to a comparison routine to see if the rest of the string matches. If it does you return the offset of the start character and if it does not, you go back to scanning the source.

You will find the one in MASM32 works OK but it is a good idea to write your own as it tunes you to writing your own algorithms and you can make dedicated algos then if you need them.

Regards,

hutch at movsd dot com
Posted on 2004-06-27 02:30:28 by hutch--
Hi Claus,

I am very sorry I did not respond earlier, I missed this thread in the RSS feed. As others have said, I use GoAsm and tend to post in that syntax as I am better set up to test with it. Everybody appears to have answered your syntax questions, GoAsm is very close in syntax to MASM except for the jmp > < stuff and FRAME/ENDF instead of PROC/ENDP. There are a few other differences but they are minor, mostly scoping of labels, GoAsm has much more powerful scoping than MASM. In the code posted you can just leave out the > or < completely and change the FRAME/ENDF.
Posted on 2004-06-27 02:55:36 by donkey
Hi donkey,

Okay, I think every question is answered, by now.

Thanks, again.
Posted on 2004-06-27 05:46:15 by ndn4u
OK,

just a new problem with Instr:

I want to search a string which has nullchars inside. I know the length of the string, so it shouldn't be a problem. Of course, there is one, as my program chrashes less than a second after terminating the Instr-Proc, although the Instr-function replied the right value.

Is there any problem with this function:


InstrEx PROC StartPos:DWORD, String:DWORD, SubString:DWORD, StrLength:DWORD

mov eax, StrLength
add eax, String
mov StrLength, eax

mov eax, String

dec eax
dec eax
add eax, StartPos

;find first match of the first char
FindFirst:

inc eax

cmp StrLength, eax
je NotFound

mov dl, [eax]
mov ecx, SubString
mov dh, [ecx]

cmp dl, dh
je FoundFirst

cmp eax, ebx
je NotFound

jmp FindFirst

FoundFirst:
push eax
mov ecx, SubString
dec ecx
dec eax

CompareLoop: inc ecx
inc eax

cmp StrLength, eax
je FalseFirst

mov dl, [eax]
mov dh, [ecx]

cmp dh, 0
je Found

cmp dh, dl
je CompareLoop

FalseFirst:
pop eax
jmp FindFirst

Found: pop eax
sub eax, String
jmp Done

NotFound: mov eax, 0

Done: ret
InstrEx ENDP


Regards,
Claus
Posted on 2004-06-27 13:03:04 by ndn4u