Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

239 lines
5.7 KiB

  1. page ,132
  2. title strcat - concatenate (append) one string to another
  3. ;***
  4. ;strcat.asm - contains strcat() and strcpy() routines
  5. ;
  6. ; Copyright (c) 1985-2001, Microsoft Corporation. All rights reserved.
  7. ;
  8. ;Purpose:
  9. ; STRCAT concatenates (appends) a copy of the source string to the
  10. ; end of the destination string, returning the destination string.
  11. ;
  12. ;Revision History:
  13. ; 04-21-87 SKS Rewritten to be fast and small, added file header
  14. ; 05-17-88 SJM Add model-independent (large model) ifdef
  15. ; 07-27-88 SJM Rewritten to be 386-specific and to include strcpy
  16. ; 08-29-88 JCR 386 cleanup...
  17. ; 10-07-88 JCR Correct off-by-1 strcat bug; optimize ecx=-1
  18. ; 10-25-88 JCR General cleanup for 386-only code
  19. ; 03-23-90 GJF Changed to _stdcall. Also, fixed the copyright.
  20. ; 05-10-91 GJF Back to _cdecl, sigh...
  21. ; 04-23-93 GJF Tuned for the 486.
  22. ; 04-30-93 GJF If (4*K + 1)-st char was null, didn't copy/cat it
  23. ; it properly.
  24. ; 06-16-93 GJF Added .FPO directive.
  25. ; 05-01-95 GJF New, faster version from Intel!
  26. ; 11-13-95 GJF Aligned strcat on paragraph boundary.
  27. ; 06-12-01 PML inc->add 1, dec->sub 1 for Pentium 4 perf (vs7#267015)
  28. ;
  29. ;*******************************************************************************
  30. .xlist
  31. include cruntime.inc
  32. .list
  33. page
  34. ;***
  35. ;char *strcat(dst, src) - concatenate (append) one string to another
  36. ;
  37. ;Purpose:
  38. ; Concatenates src onto the end of dest. Assumes enough
  39. ; space in dest.
  40. ;
  41. ; Algorithm:
  42. ; char * strcat (char * dst, char * src)
  43. ; {
  44. ; char * cp = dst;
  45. ;
  46. ; while( *cp )
  47. ; ++cp; /* Find end of dst */
  48. ; while( *cp++ = *src++ )
  49. ; ; /* Copy src to end of dst */
  50. ; return( dst );
  51. ; }
  52. ;
  53. ;Entry:
  54. ; char *dst - string to which "src" is to be appended
  55. ; const char *src - string to be appended to the end of "dst"
  56. ;
  57. ;Exit:
  58. ; The address of "dst" in EAX
  59. ;
  60. ;Uses:
  61. ; EAX, ECX
  62. ;
  63. ;Exceptions:
  64. ;
  65. ;*******************************************************************************
  66. page
  67. ;***
  68. ;char *strcpy(dst, src) - copy one string over another
  69. ;
  70. ;Purpose:
  71. ; Copies the string src into the spot specified by
  72. ; dest; assumes enough room.
  73. ;
  74. ; Algorithm:
  75. ; char * strcpy (char * dst, char * src)
  76. ; {
  77. ; char * cp = dst;
  78. ;
  79. ; while( *cp++ = *src++ )
  80. ; ; /* Copy src over dst */
  81. ; return( dst );
  82. ; }
  83. ;
  84. ;Entry:
  85. ; char * dst - string over which "src" is to be copied
  86. ; const char * src - string to be copied over "dst"
  87. ;
  88. ;Exit:
  89. ; The address of "dst" in EAX
  90. ;
  91. ;Uses:
  92. ; EAX, ECX
  93. ;
  94. ;Exceptions:
  95. ;*******************************************************************************
  96. CODESEG
  97. % public strcat, strcpy ; make both functions available
  98. strcpy proc
  99. push edi ; preserve edi
  100. mov edi,[esp+8] ; edi points to dest string
  101. jmp short copy_start
  102. strcpy endp
  103. align 16
  104. strcat proc
  105. .FPO ( 0, 2, 0, 0, 0, 0 )
  106. mov ecx,[esp+4] ; ecx -> dest string
  107. push edi ; preserve edi
  108. test ecx,3 ; test if string is aligned on 32 bits
  109. je short find_end_of_dest_string_loop
  110. dest_misaligned: ; simple byte loop until string is aligned
  111. mov al,byte ptr [ecx]
  112. add ecx,1
  113. test al,al
  114. je short start_byte_3
  115. test ecx,3
  116. jne short dest_misaligned
  117. align 4
  118. find_end_of_dest_string_loop:
  119. mov eax,dword ptr [ecx] ; read 4 bytes
  120. mov edx,7efefeffh
  121. add edx,eax
  122. xor eax,-1
  123. xor eax,edx
  124. add ecx,4
  125. test eax,81010100h
  126. je short find_end_of_dest_string_loop
  127. ; found zero byte in the loop
  128. mov eax,[ecx - 4]
  129. test al,al ; is it byte 0
  130. je short start_byte_0
  131. test ah,ah ; is it byte 1
  132. je short start_byte_1
  133. test eax,00ff0000h ; is it byte 2
  134. je short start_byte_2
  135. test eax,0ff000000h ; is it byte 3
  136. je short start_byte_3
  137. jmp short find_end_of_dest_string_loop
  138. ; taken if bits 24-30 are clear and bit
  139. ; 31 is set
  140. start_byte_3:
  141. lea edi,[ecx - 1]
  142. jmp short copy_start
  143. start_byte_2:
  144. lea edi,[ecx - 2]
  145. jmp short copy_start
  146. start_byte_1:
  147. lea edi,[ecx - 3]
  148. jmp short copy_start
  149. start_byte_0:
  150. lea edi,[ecx - 4]
  151. ; jmp short copy_start
  152. ; edi points to the end of dest string.
  153. copy_start::
  154. mov ecx,[esp+0ch] ; ecx -> sorc string
  155. test ecx,3 ; test if string is aligned on 32 bits
  156. je short main_loop_entrance
  157. src_misaligned: ; simple byte loop until string is aligned
  158. mov dl,byte ptr [ecx]
  159. add ecx,1
  160. test dl,dl
  161. je short byte_0
  162. mov [edi],dl
  163. add edi,1
  164. test ecx,3
  165. jne short src_misaligned
  166. jmp short main_loop_entrance
  167. main_loop: ; edx contains first dword of sorc string
  168. mov [edi],edx ; store one more dword
  169. add edi,4 ; kick dest pointer
  170. main_loop_entrance:
  171. mov edx,7efefeffh
  172. mov eax,dword ptr [ecx] ; read 4 bytes
  173. add edx,eax
  174. xor eax,-1
  175. xor eax,edx
  176. mov edx,[ecx] ; it's in cache now
  177. add ecx,4 ; kick dest pointer
  178. test eax,81010100h
  179. je short main_loop
  180. ; found zero byte in the loop
  181. ; main_loop_end:
  182. test dl,dl ; is it byte 0
  183. je short byte_0
  184. test dh,dh ; is it byte 1
  185. je short byte_1
  186. test edx,00ff0000h ; is it byte 2
  187. je short byte_2
  188. test edx,0ff000000h ; is it byte 3
  189. je short byte_3
  190. jmp short main_loop ; taken if bits 24-30 are clear and bit
  191. ; 31 is set
  192. byte_3:
  193. mov [edi],edx
  194. mov eax,[esp+8] ; return in eax pointer to dest string
  195. pop edi
  196. ret
  197. byte_2:
  198. mov [edi],dx
  199. mov eax,[esp+8] ; return in eax pointer to dest string
  200. mov byte ptr [edi+2],0
  201. pop edi
  202. ret
  203. byte_1:
  204. mov [edi],dx
  205. mov eax,[esp+8] ; return in eax pointer to dest string
  206. pop edi
  207. ret
  208. byte_0:
  209. mov [edi],dl
  210. mov eax,[esp+8] ; return in eax pointer to dest string
  211. pop edi
  212. ret
  213. strcat endp
  214. end