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

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


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?

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
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

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


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

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 .
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

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

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 


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

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.



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--