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