I have test several times about Instring function, found a bug, I use the following sample to test:

.data
buffer1 db "ini;txt;",0
buffer2 db "tst;",0

.code

invoke Instring, 1, offset buffer1, offset buffer2

it should be return 0( not found buffer2 in buffer1), but the returened eax is 0Ah, I wanna know where it produced the bug?

dREAMtHEATER
Posted on 2002-06-29 11:07:48 by dREAMtHEATER
Use this instead:
strstr proc pszHaystack:PTR BYTE, pszNeedle:PTR BYTE, dwCaseSensitive:DWORD

push esi
push edi
xor eax, eax
xor ecx, ecx
xor edx, edx
mov esi, [pszHaystack]
mov edi, [pszNeedle]
@@char: mov al, byte ptr [esi]
mov ah, byte ptr [edi]
cmp [dwCaseSensitive], 0
jne @@cmp1
cmp al, "Z"
ja @@cmp0
cmp al, "A"
jb @@cmp0
add al, 32
@@cmp0: cmp [dwCaseSensitive], 0
jne @@cmp1
cmp ah, "Z"
ja @@cmp1
cmp ah, "A"
jb @@cmp1
add ah, 32
@@cmp1: cmp al, ah
jne @@next
inc ecx
mov eax, esi
inc edi
inc esi
cmp byte ptr [esi], 0
je @@quit
inc eax
cmp byte ptr [edi], 0
je @@quit
jmp @@char
@@next: mov edi, [pszNeedle]
test ecx, ecx
setz dl
add esi, edx
xor ecx, ecx
xor eax, eax
cmp byte ptr [esi], 0
jne @@char
@@quit: sub eax, ecx
pop edi
pop esi
ret
strstr endp

invoke strstr, ADDR buffer1, ADDR buffer2, 1
:)
Posted on 2002-06-29 11:54:21 by comrade
it works fine to me ..(optimize version of instring)



InString proc startpos:DWORD,lpSource:DWORD,lpPattern:DWORD
push ebx
push esi
push edi


invoke StrLen,lpPattern ; pattern length
push eax ;because of strlen
invoke StrLen,lpSource ; mov sLen, eax ; source length


mov ebx,startpos

pop edx

cmp ebx,1
jb @ER
cmp eax,ebx
jg @F
@ER:


mov eax, -2
jmp isOut ; exit if startpos is past end OR exit if startpos not 1 or greater
@@:
dec ebx ; ; correct from 1 to 0 based index

sub eax,edx

jg @F
mov eax, -1
jmp isOut ; exit if pattern longer than source
@@:
inc eax
mov esi, lpSource
mov sLen, eax


; ----------------
; setup loop code
; ----------------




add esi,eax ;the order is like this to prevent stalls


neg eax ; invert sign

mov edi, lpPattern


dec edx ;to save dec later


mov cl,[edi] ; get 1st char in pattern

push edx


add eax,ebx ;add startpos


;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@




Scan_Loop:
cmp cl, [esi+eax]
je Pre_Match
@set_counter:
inc eax
jnz Scan_Loop ; the loop set eax to set if not found
jmp @loopout

Pre_Match:
mov edx,[esp] ; we have done dec edx before the push so we dont need to do mov ch,[edi+edx-1]
lea ebx,[esi+eax] ;
mov ch, [edi+edx] ; get the last char of the pattern in here .
Test_Match:
cmp ch, [ebx+edx] ; stall . but only one time per prematch..
jne @set_counter ; jump back on mismatc;
dec edx
mov ch, [edi+edx]
jnz Test_Match


add eax,sLen
inc eax


@loopout:
add esp,4 ; instead of this . make local var and save edx there
isOut:
pop edi
pop esi
pop ebx
ret



InString endp
Posted on 2002-06-29 12:35:27 by eko
an alternative way is to use the C library,
it's like comrade's strstr function but without the case feature.
includelib msvcrt.lib 

strstr PROTO C :PTR BYTE, :PTR BYTE

.data
szHaystack db "haystack",0
szNeedle db "stack",0

.code
invoke strstr, addr szHaystack, addr szNeedle

;strstr returns a pointer to the beginning of the
;substring or 0 if the substring is not found
Posted on 2002-06-29 13:09:57 by savage
Currently the algo does not exit the main scan loop so it runs to the end of the string and exits in the compare loop. I am in the middle of writing something complex at the moment so I will finish off the optimisations that EKO designed when I get a bit more time.

Regards,

hutch@movsd.com

LATER: I have posted a later version that uses an optimisation designed by EKO in the MASM32 forum.
Posted on 2002-06-30 00:25:12 by hutch--