xref: /reactos/sdk/lib/ucrt/string/i386/memccpy.s (revision 94eb4751)
1#include <asm.inc>
2#if 0
3        page    ,132
4        title   memccpy - copy bytes until character found
5;***
6;memccpy.asm - copy bytes until a character is found
7;
8;       Copyright (c) Microsoft Corporation. All rights reserved.
9;
10;Purpose:
11;       defines _memccpy() - copies bytes until a specifed character
12;       is found, or a maximum number of characters have been copied.
13;
14;*******************************************************************************
15
16        .xlist
17        include cruntime.inc
18        .list
19
20page
21;***
22;char *_memccpy(dest, src, _c, count) - copy bytes until character found
23;
24;Purpose:
25;       Copies bytes from src to dest until count bytes have been
26;       copied, or up to and including the character _c, whichever
27;       comes first.
28;
29;       Algorithm:
30;       char *
31;       _memccpy (dest, src, _c, count)
32;             char *dest, *src, _c;
33;             unsigned int count;
34;             {
35;             while (count && (*dest++ = *src++) != _c)
36;                     count--;
37;
38;             return(count ? dest : NULL);
39;             }
40;
41;Entry:
42;       char *dest - pointer to memory to receive copy
43;       char *src - source of bytes
44;       char _c - character to stop copy at
45;       int count - max number of bytes to copy
46;
47;Exit:
48;       returns pointer to byte immediately after _c in dest;
49;       returns NULL if _c was never found
50;
51;Uses:
52;
53;Exceptions:
54;
55;*******************************************************************************
56#endif
57
58        .code
59
60        public  __memccpy
61.PROC __memccpy
62        // dest:ptr byte, \
63        // src:ptr byte, \
64        // _c:byte, \
65        // count:DWORD
66
67        //OPTION PROLOGUE:NONE, EPILOGUE:NONE
68
69        FPO    0, 4, 0, 0, 0, 0
70
71        mov     ecx,[esp + HEX(10)] // ecx = max byte count
72        push    ebx             // save ebx
73
74        test    ecx,ecx         // if it's nothing to move
75        jz      ret_zero_len    // restore ebx, and return NULL
76
77        mov     bh,[esp + HEX(10)]  // bh = byte to look for
78        push    esi             // save esi
79
80        test    ecx,1           // test if counter is odd or even
81
82        mov     eax,[esp + HEX(0c)] // eax = dest   , don't affect flags
83        mov     esi,[esp + HEX(10)] // esi = source , don't affect flags
84
85//       nop
86        jz      lupe2           // if counter is even, do double loop
87                                // else do one iteration, and drop into double loop
88        mov     bl,[esi]        // get first byte into bl
89        add     esi,1           // kick src (esi points to src)
90
91        mov     [eax],bl        // store it in dest
92        add     eax,1           // kick dest
93
94        cmp     bl,bh           // see if we just moved the byte
95        je      short toend
96
97        sub     ecx,1           // decrement counter
98        jz      retnull         // drop into double loop if nonzero
99
100lupe2:
101        mov     bl,[esi]        // get first byte into bl
102        add     esi,2           // kick esi (src)
103
104        cmp     bl,bh           // check if we just moved the byte (from bl)
105        je      toend_mov_inc   // store bl & exit
106
107        mov     [eax],bl        // store first byte from bl
108        mov     bl,[esi - 1]    // get second byte  into bl
109
110        mov     [eax + 1],bl    // store second byte from bl
111        add     eax,2           // kick eax (dest)
112
113        cmp     bl,bh           // see if we just moved the byte
114        je      short toend     // end of string
115
116        sub     ecx,2           // modify counter, and if nonzero continue
117        jnz     lupe2           // else drop out & return NULL
118
119retnull:
120        pop     esi
121ret_zero_len:
122        xor     eax,eax         // null pointer
123        pop     ebx
124
125        ret                     // _cdecl return
126
127toend_mov_inc:
128        mov     [eax],bl        // store first byte from bl
129        add     eax,1           // eax points right after the value
130
131toend:  pop     esi
132        pop     ebx
133
134        ret                     // _cdecl return
135
136.ENDP // __memccpy
137
138        end
139