home *** CD-ROM | disk | FTP | other *** search
- page ,132
- title memchr - search memory for a given character
- ;***
- ;memchr.asm - search block of memory for a given character
- ;
- ; Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved.
- ;
- ;Purpose:
- ; defines memchr() - search memory until a character is
- ; found or a limit is reached.
- ;
- ;*******************************************************************************
-
- .xlist
- include cruntime.inc
- .list
-
- page
- ;***
- ;char *memchr(buf, chr, cnt) - search memory for given character.
- ;
- ;Purpose:
- ; Searched at buf for the given character, stopping when chr is
- ; first found or cnt bytes have been searched through.
- ;
- ; Algorithm:
- ; char *
- ; memchr (buf, chr, cnt)
- ; char *buf;
- ; int chr;
- ; unsigned cnt;
- ; {
- ; while (cnt && *buf++ != c)
- ; cnt--;
- ; return(cnt ? --buf : NULL);
- ; }
- ;
- ;Entry:
- ; char *buf - memory buffer to be searched
- ; char chr - character to search for
- ; unsigned cnt - max number of bytes to search
- ;
- ;Exit:
- ; returns pointer to first occurence of chr in buf
- ; returns NULL if chr not found in the first cnt bytes
- ;
- ;Uses:
- ;
- ;Exceptions:
- ;
- ;*******************************************************************************
-
- CODESEG
-
- public memchr
- memchr proc
-
- .FPO ( 0, 1, 0, 0, 0, 0 )
-
- mov eax,[esp+0ch] ; eax = count
- push ebx ; Preserve ebx
-
- test eax,eax ; check if count=0
- jz short retnull ; if count=0, leave
-
- mov edx,[esp+8] ; edx = buffer
- xor ebx,ebx
-
- mov bl,[esp+0ch] ; bl = search char
-
- test edx,3 ; test if string is aligned on 32 bits
- jz short main_loop_start
-
- str_misaligned: ; simple byte loop until string is aligned
- mov cl,byte ptr [edx]
- inc edx
- xor cl,bl
- je short found
- dec eax ; counter--
- jz short retnull
- test edx,3 ; already aligned ?
- jne short str_misaligned
-
- main_loop_start:
- sub eax,4
- jb short tail_less_then_4
-
- ; set all 4 bytes of ebx to [value]
- push edi ; Preserve edi
- mov edi,ebx ; edi=0/0/0/char
- shl ebx,8 ; ebx=0/0/char/0
- add ebx,edi ; ebx=0/0/char/char
- mov edi,ebx ; edi=0/0/char/char
- shl ebx,10h ; ebx=char/char/0/0
- add ebx,edi ; ebx = all 4 bytes = [search char]
- jmp short main_loop_entry ; ecx >=0
-
- return_from_main:
- pop edi
-
- tail_less_then_4:
- add eax,4
- jz retnull
-
- tail_loop: ; 0 < eax < 4
- mov cl,byte ptr [edx]
- inc edx
- xor cl,bl
- je short found
- dec eax
- jnz short tail_loop
- retnull:
- pop ebx
- ret ; _cdecl return
-
- main_loop:
- sub eax,4
- jb short return_from_main
- main_loop_entry:
- mov ecx,dword ptr [edx] ; read 4 bytes
-
- xor ecx,ebx ; ebx is byte\byte\byte\byte
- mov edi,7efefeffh
-
- add edi,ecx
- xor ecx,-1
-
- xor ecx,edi
- add edx,4
-
- and ecx,81010100h
- je short main_loop
-
- ; found zero byte in the loop?
- char_is_found:
- mov ecx,[edx - 4]
- xor cl,bl ; is it byte 0
- je short byte_0
- xor ch,bl ; is it byte 1
- je short byte_1
- shr ecx,10h ; is it byte 2
- xor cl,bl
- je short byte_2
- xor ch,bl ; is it byte 3
- je short byte_3
- jmp short main_loop ; taken if bits 24-30 are clear and bit
- ; 31 is set
-
- byte_3:
- pop edi ; restore edi
- found:
- lea eax,[edx - 1]
- pop ebx ; restore ebx
- ret ; _cdecl return
-
- byte_2:
- lea eax,[edx - 2]
- pop edi
- pop ebx
- ret ; _cdecl return
-
- byte_1:
- lea eax,[edx - 3]
- pop edi
- pop ebx
- ret ; _cdecl return
-
- byte_0:
- lea eax,[edx - 4]
- pop edi ; restore edi
- pop ebx ; restore ebx
- ret ; _cdecl return
-
- memchr endp
- end
-