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