
Only Pointers need to be supplied, the string size will be determined on the fly.
Theres a Unicode and Ascii version.
Its pretty fast already (it beats FindString())

Code (run without Debugger!):
Code: Select all
EnableExplicit
Global TestString.s
Global Signature.s
Global Index.i
Global T1.q, R1.i, *A1
Global T2.q, R2.i, *A2
Procedure.i LocStrW(*Input,*Signature);Unicode
!mov rcx,[p.p_Input]
!mov rdx,[p.p_Signature]
!xor rax,rax
!mov r10,rcx
!cmp word[rdx],0h
!je LocStr_Return
!LocStr_Loop:
!cmp word[rcx],0h
!je LocStr_Return
!mov bx,word[rcx]
!cmp bx,word[rdx]
!jne LocStr_Next
!lea r8,[rcx+2h]
!lea r9,[rdx+2h]
!LocStr_Match:
!cmp word[r9],0h
!je LocStr_Result
!cmp word[r8],0h
!je LocStr_Next
!mov bx,word[r8]
!cmp bx,word[r9]
!jne LocStr_Next
!lea r8,[r8+2h]
!lea r9,[r9+2h]
!jmp LocStr_Match
!LocStr_Result:
!sub rcx,r10
!lea rax,[rcx+2h]
!shr rax,1h
!jmp LocStr_Return
!LocStr_Next:
!lea rcx,[rcx+2h]
!jmp LocStr_Loop
!LocStr_Return:
ProcedureReturn
EndProcedure
Procedure.i LocStrA(*Input,*Signature);Ascii
!mov rcx,[p.p_Input]
!mov rdx,[p.p_Signature]
!xor rax,rax
!mov r10,rcx
!cmp byte[rdx],0h
!je LocStr_Return
!LocStr_Loop:
!cmp byte[rcx],0h
!je LocStr_Return
!mov bl,byte[rcx]
!cmp bl,byte[rdx]
!jne LocStr_Next
!lea r8,[rcx+1h]
!lea r9,[rdx+1h]
!LocStr_Match:
!cmp byte[r9],0h
!je LocStr_Result
!cmp byte[r8],0h
!je LocStr_Next
!mov bl,byte[r8]
!cmp bl,byte[r9]
!jne LocStr_Next
!inc r8
!inc r9
!jmp LocStr_Match
!LocStr_Result:
!sub rcx,r10
!lea rax,[rcx+1h]
!jmp LocStr_Return
!LocStr_Next:
!inc rcx
!jmp LocStr_Loop
!LocStr_Return:
ProcedureReturn
EndProcedure
#Tries = 2e2
TestString = Space(1000000) + "!#"
Signature = "!"
*A1 = Ascii(TestString)
*A2 = Ascii(Signature)
T1 = ElapsedMilliseconds()
For Index = 1 To #Tries;10000000
R1 = FindString(TestString,Signature)
Next
T1 = ElapsedMilliseconds() - T1
T2 = ElapsedMilliseconds()
For Index = 1 To #Tries;10000000
R2 = LocStrW(@TestString,@Signature);LocStrA(*A1,*A2)
Next
T2 = ElapsedMilliseconds() - T2
MessageRequester("Result",
"T1: " + Str(T1) + #CR$ + "R1: " + Str(R1) + #CR$ + #CR$ +
"T2: " + Str(T2) + #CR$ + "R2: " + Str(R2))
End