page ,132 title memccpy - copy bytes until character found ;*** ;memccpy.asm - copy bytes until a character is found ; ; Copyright (c) 1985-2001, Microsoft Corporation. All rights reserved. ; ;Purpose: ; defines _memccpy() - copies bytes until a specifed character ; is found, or a maximum number of characters have been copied. ; ;Revision History: ; 05-16-84 RN initial version ; 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 Minor 386 adjustments ; 10-25-88 JCR General cleanup for 386-only code ; 03-23-90 GJF Changed to _stdcall. Also, fixed the copyright. ; 01-17-91 GJF ANSI naming. ; 05-10-91 GJF Back to _cdecl, sigh... ; 10-27-92 SKS Avoid using a MASM keyword ("C") as a parameter name ; 01-19-95 GJF Faster version courtesy of Intel Israel. ; 01-24-95 GJF Added FPO directive. ; 06-12-01 PML inc->add 1, dec->sub 1 for Pentium 4 perf (vs7#267015) ; ;******************************************************************************* .xlist include cruntime.inc .list page ;*** ;char *_memccpy(dest, src, _c, count) - copy bytes until character found ; ;Purpose: ; Copies bytes from src to dest until count bytes have been ; copied, or up to and including the character _c, whichever ; comes first. ; ; Algorithm: ; char * ; _memccpy (dest, src, _c, count) ; char *dest, *src, _c; ; unsigned int count; ; { ; while (count && (*dest++ = *src++) != _c) ; count--; ; ; return(count ? dest : NULL); ; } ; ;Entry: ; char *dest - pointer to memory to receive copy ; char *src - source of bytes ; char _c - character to stop copy at ; int count - max number of bytes to copy ; ;Exit: ; returns pointer to byte immediately after _c in dest; ; returns NULL if _c was never found ; ;Uses: ; ;Exceptions: ; ;******************************************************************************* CODESEG public _memccpy _memccpy proc .FPO ( 0, 4, 0, 0, 0, 0 ) mov ecx,[esp + 10h] ; ecx = max byte count push ebx ; save ebx test ecx,ecx ; if it's nothing to move jz ret_zero_len ; restore ebx, and return NULL mov bh,[esp + 10h] ; bh = byte to look for push esi ; save esi test ecx,1 ; test if counter is odd or even mov eax,[esp + 0ch] ; eax = dest , don't affect flags mov esi,[esp + 10h] ; esi = source , don't affect flags ; nop jz lupe2 ; if counter is even, do double loop ; else do one iteration, and drop into double loop mov bl,[esi] ; get first byte into bl add esi,1 ; kick src (esi points to src) mov [eax],bl ; store it in dest add eax,1 ; kick dest cmp bl,bh ; see if we just moved the byte je short toend sub ecx,1 ; decrement counter jz retnull ; drop into double loop if nonzero lupe2: mov bl,[esi] ; get first byte into bl add esi,2 ; kick esi (src) cmp bl,bh ; check if we just moved the byte (from bl) je toend_mov_inc ; store bl & exit mov [eax],bl ; store first byte from bl mov bl,[esi - 1] ; get second byte into bl mov [eax + 1],bl ; store second byte from bl add eax,2 ; kick eax (dest) cmp bl,bh ; see if we just moved the byte je short toend ; end of string sub ecx,2 ; modify counter, and if nonzero continue jnz lupe2 ; else drop out & return NULL retnull: pop esi ret_zero_len: xor eax,eax ; null pointer pop ebx ret ; _cdecl return toend_mov_inc: mov [eax],bl ; store first byte from bl add eax,1 ; eax points right after the value toend: pop esi pop ebx ret ; _cdecl return _memccpy endp end