Source code of Windows XP (NT5)
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.

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