xref: /reactos/sdk/lib/ucrt/string/i386/strcat.s (revision 94eb4751)
1#include <asm.inc>
2#if 0
3        page    ,132
4        title   strcat - concatenate (append) one string to another
5;***
6;strcat.asm - contains strcat() and strcpy() routines
7;
8;       Copyright (c) Microsoft Corporation. All rights reserved.
9;
10;Purpose:
11;       STRCAT concatenates (appends) a copy of the source string to the
12;       end of the destination string, returning the destination string.
13;
14;*******************************************************************************
15
16        .xlist
17        include cruntime.inc
18        .list
19
20
21page
22;***
23;char *strcat(dst, src) - concatenate (append) one string to another
24;
25;Purpose:
26;       Concatenates src onto the end of dest.  Assumes enough
27;       space in dest.
28;
29;       Algorithm:
30;       char * strcat (char * dst, char * src)
31;       {
32;           char * cp = dst;
33;
34;           while( *cp )
35;                   ++cp;           /* Find end of dst */
36;           while( *cp++ = *src++ )
37;                   ;               /* Copy src to end of dst */
38;           return( dst );
39;       }
40;
41;Entry:
42;       char *dst - string to which "src" is to be appended
43;       const char *src - string to be appended to the end of "dst"
44;
45;Exit:
46;       The address of "dst" in EAX
47;
48;Uses:
49;       EAX, ECX
50;
51;Exceptions:
52;
53;*******************************************************************************
54
55page
56;***
57;char *strcpy(dst, src) - copy one string over another
58;
59;Purpose:
60;       Copies the string src into the spot specified by
61;       dest; assumes enough room.
62;
63;       Algorithm:
64;       char * strcpy (char * dst, char * src)
65;       {
66;           char * cp = dst;
67;
68;           while( *cp++ = *src++ )
69;                   ;               /* Copy src over dst */
70;           return( dst );
71;       }
72;
73;Entry:
74;       char * dst - string over which "src" is to be copied
75;       const char * src - string to be copied over "dst"
76;
77;Exit:
78;       The address of "dst" in EAX
79;
80;Uses:
81;       EAX, ECX
82;
83;Exceptions:
84;*******************************************************************************
85#endif
86
87
88        .code
89
90       public _strcat
91       public _strcpy      // make both functions available
92.PROC _strcpy
93        // dst:ptr byte, \
94        // src:ptr byte
95
96        //OPTION PROLOGUE:NONE, EPILOGUE:NONE
97
98        push    edi                 // preserve edi
99        mov     edi,[esp+8]         // edi points to dest string
100        jmp     short copy_start
101
102.ENDP // _strcpy
103
104        align   16
105
106.PROC _strcat
107        // dst:ptr byte, \
108        // src:ptr byte
109
110        //OPTION PROLOGUE:NONE, EPILOGUE:NONE
111
112        FPO    0, 2, 0, 0, 0, 0
113
114        mov     ecx,[esp+4]         // ecx -> dest string
115        push    edi                 // preserve edi
116        test    ecx,3               // test if string is aligned on 32 bits
117        je      short find_end_of_dest_string_loop
118
119dest_misaligned:                    // simple byte loop until string is aligned
120        mov     al,byte ptr [ecx]
121        add     ecx,1
122        test    al,al
123        je      short start_byte_3
124        test    ecx,3
125        jne     short dest_misaligned
126
127        align   4
128
129find_end_of_dest_string_loop:
130        mov     eax,dword ptr [ecx] // read 4 bytes
131        mov     edx,HEX(7efefeff)
132        add     edx,eax
133        xor     eax,-1
134        xor     eax,edx
135        add     ecx,4
136        test    eax,HEX(81010100)
137        je      short find_end_of_dest_string_loop
138        // found zero byte in the loop
139        mov     eax,[ecx - 4]
140        test    al,al               // is it byte 0
141        je      short start_byte_0
142        test    ah,ah               // is it byte 1
143        je      short start_byte_1
144        test    eax,HEX(00ff0000)       // is it byte 2
145        je      short start_byte_2
146        test    eax,HEX(0ff000000)      // is it byte 3
147        je      short start_byte_3
148        jmp     short find_end_of_dest_string_loop
149                                    // taken if bits 24-30 are clear and bit
150                                    // 31 is set
151start_byte_3:
152        lea     edi,[ecx - 1]
153        jmp     short copy_start
154start_byte_2:
155        lea     edi,[ecx - 2]
156        jmp     short copy_start
157start_byte_1:
158        lea     edi,[ecx - 3]
159        jmp     short copy_start
160start_byte_0:
161        lea     edi,[ecx - 4]
162//       jmp     short copy_start
163
164//       edi points to the end of dest string.
165GLOBAL_LABEL copy_start
166        mov     ecx,[esp+HEX(0c)]       // ecx -> sorc string
167        test    ecx,3               // test if string is aligned on 32 bits
168        je      short main_loop_entrance
169
170src_misaligned:                     // simple byte loop until string is aligned
171        mov     dl,byte ptr [ecx]
172        add     ecx,1
173        test    dl,dl
174        je      short byte_0
175        mov     [edi],dl
176        add     edi,1
177        test    ecx,3
178        jne     short src_misaligned
179        jmp     short main_loop_entrance
180
181main_loop:                          // edx contains first dword of sorc string
182        mov     [edi],edx           // store one more dword
183        add     edi,4               // kick dest pointer
184main_loop_entrance:
185        mov     edx,HEX(7efefeff)
186        mov     eax,dword ptr [ecx] // read 4 bytes
187
188        add     edx,eax
189        xor     eax,-1
190
191        xor     eax,edx
192        mov     edx,[ecx]           // it's in cache now
193
194        add     ecx,4               // kick dest pointer
195        test    eax,HEX(81010100)
196
197        je      short main_loop
198        // found zero byte in the loop
199; main_loop_end:
200        test    dl,dl               // is it byte 0
201        je      short byte_0
202        test    dh,dh               // is it byte 1
203        je      short byte_1
204        test    edx,HEX(00ff0000)       // is it byte 2
205        je      short byte_2
206        test    edx,HEX(0ff000000)      // is it byte 3
207        je      short byte_3
208        jmp     short main_loop     // taken if bits 24-30 are clear and bit
209                                    // 31 is set
210byte_3:
211        mov     [edi],edx
212        mov     eax,[esp+8]         // return in eax pointer to dest string
213        pop     edi
214        ret
215byte_2:
216        mov     [edi],dx
217        mov     eax,[esp+8]         // return in eax pointer to dest string
218        mov     byte ptr [edi+2],0
219        pop     edi
220        ret
221byte_1:
222        mov     [edi],dx
223        mov     eax,[esp+8]         // return in eax pointer to dest string
224        pop     edi
225        ret
226byte_0:
227        mov     [edi],dl
228        mov     eax,[esp+8]         // return in eax pointer to dest string
229        pop     edi
230        ret
231
232.ENDP // _strcat
233
234        end
235
236