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