136 lines
3.2 KiB
NASM
136 lines
3.2 KiB
NASM
page ,132
|
|
title strstr - search for one string inside another
|
|
;***
|
|
;strstr.asm - search for one string inside another
|
|
;
|
|
; Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved.
|
|
;
|
|
;Purpose:
|
|
; defines strstr() - search for one string inside another
|
|
;
|
|
;Revision History:
|
|
; 02-02-88 SKS Rewritten from scratch. Now works correctly with
|
|
; strings > 32 KB in length. Also smaller and faster.
|
|
; 03-01-88 SKS Ensure that ES = DS right away (Small/Medium models)
|
|
; 05-18-88 SJM Add model-independent (large model) ifdef
|
|
; 08-04-88 SJM convert to cruntime/ add 32-bit support
|
|
; 08-18-88 PHG Corrected return value when src is empty string
|
|
; to conform with ANSI.
|
|
; 08-23-88 JCR Minor 386 cleanup
|
|
; 10-26-88 JCR General cleanup for 386-only code
|
|
; 03-26-90 GJF Changed to _stdcall. Also, fixed the copyright.
|
|
; 05-10-91 GJF Back to _cdecl, sigh...
|
|
;
|
|
;*******************************************************************************
|
|
|
|
.xlist
|
|
include cruntime.inc
|
|
.list
|
|
|
|
page
|
|
;***
|
|
;char *strstr(string1, string2) - search for string2 in string1
|
|
;
|
|
;Purpose:
|
|
; finds the first occurrence of string2 in string1
|
|
;
|
|
;Entry:
|
|
; char *string1 - string to search in
|
|
; char *string2 - string to search for
|
|
;
|
|
;Exit:
|
|
; returns a pointer to the first occurrence of string2 in
|
|
; string1, or NULL if string2 does not occur in string1
|
|
;
|
|
;Uses:
|
|
;
|
|
;Exceptions:
|
|
;
|
|
;*******************************************************************************
|
|
|
|
CODESEG
|
|
|
|
public strstr
|
|
strstr proc \
|
|
uses esi edi ebx, \
|
|
dst:ptr byte, \
|
|
src:ptr byte
|
|
|
|
local srclen:IWORD
|
|
|
|
|
|
mov edi, (src) ; di = src
|
|
xor eax,eax ; Scan for null at end of (src)
|
|
or ecx,-1 ; cx = -1
|
|
repnz scasb
|
|
not ecx
|
|
dec ecx
|
|
jecxz short empty_src ; src == "" ?
|
|
dec ecx ; CX = strlen(src)-1
|
|
mov (srclen),ecx
|
|
|
|
mov edi,(dst)
|
|
mov ebx,edi ; BX will keep the current offset into (dst)
|
|
|
|
xor eax,eax ; Scan for null at end of (dst)
|
|
or ecx,-1 ; cx = -1
|
|
repnz scasb
|
|
not ecx
|
|
dec ecx ; CX = strlen(dst)
|
|
|
|
mov edx,ecx ; Save strlen(dst) in DX
|
|
|
|
sub edx,(srclen) ; DX = strlen(dst) - (strlen(src)-1)
|
|
jbe short not_found ; strlen(dst) <= (strlen(src)-1)
|
|
; target is longer than source?
|
|
mov edi,ebx ; restore ES:DI = (dst)
|
|
|
|
findnext:
|
|
mov esi,IWORD ptr (src)
|
|
lodsb ; Get the first byte of the source
|
|
mov edi,ebx ; restore position in source
|
|
mov ecx,edx ; count of possible starting bytes in src
|
|
;
|
|
; CX, DX = number of bytes left in source where target can still fit
|
|
; DI, BX = current position in (dst)
|
|
; DS:SI = (src) + 1
|
|
; AL = *(src)
|
|
;
|
|
|
|
repne scasb ; find next occurrence of *(target) in dst
|
|
jne short not_found ; out of string -- return NULL
|
|
|
|
mov edx,ecx ; update count of acceptable bytes left in dst
|
|
mov ebx,edi ; save current offset in dst
|
|
|
|
mov ecx,(srclen)
|
|
jecxz short match ; single character src string?
|
|
|
|
repe cmpsb
|
|
jne short findnext
|
|
|
|
;
|
|
; Match! Return (BX-1)
|
|
;
|
|
match:
|
|
lea eax,[ebx-1]
|
|
jmp short retval
|
|
|
|
empty_src: ; empty src string, return dst (ANSI mandated)
|
|
mov eax,(dst) ; eax = dst
|
|
jmp short retval ; return
|
|
|
|
not_found:
|
|
xor eax,eax
|
|
|
|
retval:
|
|
|
|
ifdef _STDCALL_
|
|
ret 2*DPSIZE ; _stdcall return
|
|
else
|
|
ret ; _cdecl return
|
|
endif
|
|
|
|
strstr endp
|
|
end
|