xref: /reactos/sdk/lib/ucrt/string/i386/memccpy.s (revision 94eb4751)
1*94eb4751STimo Kreuzer#include <asm.inc>
2*94eb4751STimo Kreuzer#if 0
34fec953eSTimo Kreuzer        page    ,132
44fec953eSTimo Kreuzer        title   memccpy - copy bytes until character found
54fec953eSTimo Kreuzer;***
64fec953eSTimo Kreuzer;memccpy.asm - copy bytes until a character is found
74fec953eSTimo Kreuzer;
84fec953eSTimo Kreuzer;       Copyright (c) Microsoft Corporation. All rights reserved.
94fec953eSTimo Kreuzer;
104fec953eSTimo Kreuzer;Purpose:
114fec953eSTimo Kreuzer;       defines _memccpy() - copies bytes until a specifed character
124fec953eSTimo Kreuzer;       is found, or a maximum number of characters have been copied.
134fec953eSTimo Kreuzer;
144fec953eSTimo Kreuzer;*******************************************************************************
154fec953eSTimo Kreuzer
164fec953eSTimo Kreuzer        .xlist
174fec953eSTimo Kreuzer        include cruntime.inc
184fec953eSTimo Kreuzer        .list
194fec953eSTimo Kreuzer
204fec953eSTimo Kreuzerpage
214fec953eSTimo Kreuzer;***
224fec953eSTimo Kreuzer;char *_memccpy(dest, src, _c, count) - copy bytes until character found
234fec953eSTimo Kreuzer;
244fec953eSTimo Kreuzer;Purpose:
254fec953eSTimo Kreuzer;       Copies bytes from src to dest until count bytes have been
264fec953eSTimo Kreuzer;       copied, or up to and including the character _c, whichever
274fec953eSTimo Kreuzer;       comes first.
284fec953eSTimo Kreuzer;
294fec953eSTimo Kreuzer;       Algorithm:
304fec953eSTimo Kreuzer;       char *
314fec953eSTimo Kreuzer;       _memccpy (dest, src, _c, count)
324fec953eSTimo Kreuzer;             char *dest, *src, _c;
334fec953eSTimo Kreuzer;             unsigned int count;
344fec953eSTimo Kreuzer;             {
354fec953eSTimo Kreuzer;             while (count && (*dest++ = *src++) != _c)
364fec953eSTimo Kreuzer;                     count--;
374fec953eSTimo Kreuzer;
384fec953eSTimo Kreuzer;             return(count ? dest : NULL);
394fec953eSTimo Kreuzer;             }
404fec953eSTimo Kreuzer;
414fec953eSTimo Kreuzer;Entry:
424fec953eSTimo Kreuzer;       char *dest - pointer to memory to receive copy
434fec953eSTimo Kreuzer;       char *src - source of bytes
444fec953eSTimo Kreuzer;       char _c - character to stop copy at
454fec953eSTimo Kreuzer;       int count - max number of bytes to copy
464fec953eSTimo Kreuzer;
474fec953eSTimo Kreuzer;Exit:
484fec953eSTimo Kreuzer;       returns pointer to byte immediately after _c in dest;
494fec953eSTimo Kreuzer;       returns NULL if _c was never found
504fec953eSTimo Kreuzer;
514fec953eSTimo Kreuzer;Uses:
524fec953eSTimo Kreuzer;
534fec953eSTimo Kreuzer;Exceptions:
544fec953eSTimo Kreuzer;
554fec953eSTimo Kreuzer;*******************************************************************************
56*94eb4751STimo Kreuzer#endif
574fec953eSTimo Kreuzer
58*94eb4751STimo Kreuzer        .code
594fec953eSTimo Kreuzer
60*94eb4751STimo Kreuzer        public  __memccpy
61*94eb4751STimo Kreuzer.PROC __memccpy
62*94eb4751STimo Kreuzer        // dest:ptr byte, \
63*94eb4751STimo Kreuzer        // src:ptr byte, \
64*94eb4751STimo Kreuzer        // _c:byte, \
65*94eb4751STimo Kreuzer        // count:DWORD
664fec953eSTimo Kreuzer
67*94eb4751STimo Kreuzer        //OPTION PROLOGUE:NONE, EPILOGUE:NONE
684fec953eSTimo Kreuzer
69*94eb4751STimo Kreuzer        FPO    0, 4, 0, 0, 0, 0
704fec953eSTimo Kreuzer
71*94eb4751STimo Kreuzer        mov     ecx,[esp + HEX(10)] // ecx = max byte count
72*94eb4751STimo Kreuzer        push    ebx             // save ebx
734fec953eSTimo Kreuzer
74*94eb4751STimo Kreuzer        test    ecx,ecx         // if it's nothing to move
75*94eb4751STimo Kreuzer        jz      ret_zero_len    // restore ebx, and return NULL
764fec953eSTimo Kreuzer
77*94eb4751STimo Kreuzer        mov     bh,[esp + HEX(10)]  // bh = byte to look for
78*94eb4751STimo Kreuzer        push    esi             // save esi
794fec953eSTimo Kreuzer
80*94eb4751STimo Kreuzer        test    ecx,1           // test if counter is odd or even
814fec953eSTimo Kreuzer
82*94eb4751STimo Kreuzer        mov     eax,[esp + HEX(0c)] // eax = dest   , don't affect flags
83*94eb4751STimo Kreuzer        mov     esi,[esp + HEX(10)] // esi = source , don't affect flags
844fec953eSTimo Kreuzer
85*94eb4751STimo Kreuzer//       nop
86*94eb4751STimo Kreuzer        jz      lupe2           // if counter is even, do double loop
87*94eb4751STimo Kreuzer                                // else do one iteration, and drop into double loop
88*94eb4751STimo Kreuzer        mov     bl,[esi]        // get first byte into bl
89*94eb4751STimo Kreuzer        add     esi,1           // kick src (esi points to src)
904fec953eSTimo Kreuzer
91*94eb4751STimo Kreuzer        mov     [eax],bl        // store it in dest
92*94eb4751STimo Kreuzer        add     eax,1           // kick dest
934fec953eSTimo Kreuzer
94*94eb4751STimo Kreuzer        cmp     bl,bh           // see if we just moved the byte
954fec953eSTimo Kreuzer        je      short toend
964fec953eSTimo Kreuzer
97*94eb4751STimo Kreuzer        sub     ecx,1           // decrement counter
98*94eb4751STimo Kreuzer        jz      retnull         // drop into double loop if nonzero
994fec953eSTimo Kreuzer
1004fec953eSTimo Kreuzerlupe2:
101*94eb4751STimo Kreuzer        mov     bl,[esi]        // get first byte into bl
102*94eb4751STimo Kreuzer        add     esi,2           // kick esi (src)
1034fec953eSTimo Kreuzer
104*94eb4751STimo Kreuzer        cmp     bl,bh           // check if we just moved the byte (from bl)
105*94eb4751STimo Kreuzer        je      toend_mov_inc   // store bl & exit
1064fec953eSTimo Kreuzer
107*94eb4751STimo Kreuzer        mov     [eax],bl        // store first byte from bl
108*94eb4751STimo Kreuzer        mov     bl,[esi - 1]    // get second byte  into bl
1094fec953eSTimo Kreuzer
110*94eb4751STimo Kreuzer        mov     [eax + 1],bl    // store second byte from bl
111*94eb4751STimo Kreuzer        add     eax,2           // kick eax (dest)
1124fec953eSTimo Kreuzer
113*94eb4751STimo Kreuzer        cmp     bl,bh           // see if we just moved the byte
114*94eb4751STimo Kreuzer        je      short toend     // end of string
1154fec953eSTimo Kreuzer
116*94eb4751STimo Kreuzer        sub     ecx,2           // modify counter, and if nonzero continue
117*94eb4751STimo Kreuzer        jnz     lupe2           // else drop out & return NULL
1184fec953eSTimo Kreuzer
1194fec953eSTimo Kreuzerretnull:
1204fec953eSTimo Kreuzer        pop     esi
1214fec953eSTimo Kreuzerret_zero_len:
122*94eb4751STimo Kreuzer        xor     eax,eax         // null pointer
1234fec953eSTimo Kreuzer        pop     ebx
1244fec953eSTimo Kreuzer
125*94eb4751STimo Kreuzer        ret                     // _cdecl return
1264fec953eSTimo Kreuzer
1274fec953eSTimo Kreuzertoend_mov_inc:
128*94eb4751STimo Kreuzer        mov     [eax],bl        // store first byte from bl
129*94eb4751STimo Kreuzer        add     eax,1           // eax points right after the value
1304fec953eSTimo Kreuzer
1314fec953eSTimo Kreuzertoend:  pop     esi
1324fec953eSTimo Kreuzer        pop     ebx
1334fec953eSTimo Kreuzer
134*94eb4751STimo Kreuzer        ret                     // _cdecl return
1354fec953eSTimo Kreuzer
136*94eb4751STimo Kreuzer.ENDP // __memccpy
1374fec953eSTimo Kreuzer
1384fec953eSTimo Kreuzer        end
139