home *** CD-ROM | disk | FTP | other *** search
-
- ;------ SearchString - reveals Microsoft QuickBASIC's INSTR algorithm
-
- ;syntax: Found = SearchString%(BYVAL StartChar%, Source$, Search$)
- ;
- ; where:
- ;
- ; StartChar% specifies where in the source string searching is to begin,
- ; Source$ is the string being searched, and Search$ is the string to find.
- ; Found then receives the position in Source$ where Search$ is found
- ; (1-based), or zero if there was no match.
- .Model Medium,Basic
-
- .Code
-
- SearchString Proc Uses SI DI, Start:Word, Source:Word, Search:Word
-
- Cld ;insure that string instructions are forward
- Push DS ;assign ES=DS
- Pop ES
- Mov AX,Start ;put Start% into AX
-
- Mov SI,Search ;get the address for the Search$ descriptor
- Mov DX,[SI] ;put its length into DX
- Mov SI,[SI+02] ;and its address into SI
- Dec DX ;we'll handle the first character using Scasb
- Js Exit ;they slipped us a null string, so return Start%
-
- Mov DI,Source ;get the address for the Source$ descriptor
- Mov CX,[DI] ;put its length into CX
- Mov DI,[DI+02] ;and its address into DI
- Mov BX,DI ;save that in BX to see how far we searched later
-
- Dec AX ;adjust Start% so 1st character = 0 offset
- Js NotFound ;Start% was zero or negative, get out and return 0
- Add DI,AX ;advance Start% bytes into the string
- Sub CX,AX ;and consider that many fewer characters to search
- Jbe NotFound ;they tried to start past the end
-
- Lodsb ;get and skip over the first character in Search$
-
- Scan:
- Repne Scasb ;find the first character in Source$ that matches
- Jne NotFound ;if it's not there, the complete string isn't either
- Cmp CX,DX ;are we less than LEN(Search$) bytes from the end?
- Jb NotFound ;yes, so there's no point in looking further
- Or DX,DX ;was the string only one character long?
- Jz Found ;yes, so this must be it
-
- Push SI ;save the current scanning context
- Push DI
- Push CX
- Mov CX,DX ;search LEN(Search$) characters
- Repe Cmpsb ;compare the two strings
- Pop CX ;restore the context in case we have to scan again
- Pop DI
- Pop SI
- Jne Scan ;we didn't find it, keep trying
-
- Found: ;we found a match
- Sub DI,BX ;calculate how far into the string we found a match
- Mov AX,DI ;leave the result in AX for the function output
-
- Exit:
- Ret ;return to caller
-
- NotFound:
- Xor AX,AX ;return zero to show we didn't find it
- Jmp Short Exit ;and exit
-
- SearchString Endp
- End
-