windows-nt/Source/XPSP1/NT/base/crts/crtw32/string/i386/memchr.asm

187 lines
3.7 KiB
NASM
Raw Normal View History

2020-09-26 03:20:57 -05:00
page ,132
title memchr - search memory for a given character
;***
;memchr.asm - search block of memory for a given character
;
; Copyright (c) 1985-2001, Microsoft Corporation. All rights reserved.
;
;Purpose:
; defines memchr() - search memory until a character is
; found or a limit is reached.
;
;Revision History:
; 05-16-84 RN initial version
; 07-20-87 SKS rewritten for speed
; 05-17-88 SJM Add model-independent (large model) ifdef
; 08-04-88 SJM convert to cruntime/ add 32-bit support
; 08-23-88 JCR 386 cleanup
; 10-25-88 JCR General cleanup for 386-only code
; 03-23-90 GJF Changed to _stdcall. Also, fixed the copyright.
; 05-10-91 GJF Back to _cdecl, sigh...
; 05-01-95 GJF New, faster version from Intel!
;
;*******************************************************************************
.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