1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
page ,132
title strcat - concatenate (append) one string to another
;***
;strcat.asm - contains strcat() and strcpy() routines
;
; Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved.
;
;Purpose:
; STRCAT concatenates (appends) a copy of the source string to the
; end of the destination string, returning the destination string.
;
;Revision History:
; 04-21-87 SKS Rewritten to be fast and small, added file header
; 05-17-88 SJM Add model-independent (large model) ifdef
; 07-27-88 SJM Rewritten to be 386-specific and to include strcpy
; 08-29-88 JCR 386 cleanup...
; 10-07-88 JCR Correct off-by-1 strcat bug; optimize ecx=-1
; 10-25-88 JCR General cleanup for 386-only code
; 03-23-90 GJF Changed to _stdcall. Also, fixed the copyright.
; 05-10-91 GJF Back to _cdecl, sigh...
;
;*******************************************************************************
.xlist
include cruntime.inc
.list
page
;***
;char *strcat(dst, src) - concatenate (append) one string to another
;
;Purpose:
; Concatenates src onto the end of dest. Assumes enough
; space in dest.
;
; Algorithm:
; char * strcat (char * dst, char * src)
; {
; char * cp = dst;
;
; while( *cp )
; ++cp; /* Find end of dst */
; while( *cp++ = *src++ )
; ; /* Copy src to end of dst */
; return( dst );
; }
;
;Entry:
; char *dst - string to which "src" is to be appended
; const char *src - string to be appended to the end of "dst"
;
;Exit:
; The address of "dst" in AX/DX:AX
;
;Uses:
; BX, CX, DX
;
;Exceptions:
;
;*******************************************************************************
page
;***
;char *strcpy(dst, src) - copy one string over another
;
;Purpose:
; Copies the string src into the spot specified by
; dest; assumes enough room.
;
; Algorithm:
; char * strcpy (char * dst, char * src)
; {
; char * cp = dst;
;
; while( *cp++ = *src++ )
; ; /* Copy src over dst */
; return( dst );
; }
;
;Entry:
; char * dst - string over which "src" is to be copied
; const char * src - string to be copied over "dst"
;
;Exit:
; The address of "dst" in AX/DX:AX
;
;Uses:
; BX, CX, DX
;
;Exceptions:
;*******************************************************************************
CODESEG
% public strcat, strcpy ; make both functions available
strcat label proc ;--- strcat ---
clc ; carry clear = append
jmp short _docat
align @wordsize ; want to come in on a nice boundary...
strcpy label proc ;--- strcpy ---
stc ; carry set = don't append to end of string
;fall thru
; --- Common code ---
_docat proc private \
uses esi edi, \
dst:ptr byte, \
src:ptr byte
mov edi, dst ; di = dest pointer
jc short @F ; jump if not appending
; now skip to end of destination string
xor eax, eax ; search for the null terminator
or ecx,-1 ; ecx = -1
repne scasb
dec edi ; edi points to null terminator
; copy source string
@@: mov esi, src
xchg esi, edi ; now ds:esi->dst and es:edi->src
xor eax, eax ; search for null
or ecx,-1 ; ecx = -1
repne scasb ; find the length of the src string
not ecx
sub edi, ecx
xchg esi, edi ; now es:edi->dst and ds:esi->src
mov eax, ecx
shr ecx, ISHIFT ; get the double-word count
rep movsd
and eax, (ISIZE-1) ; get the byte cound
xchg ecx, eax
rep movsb ; move remaining bytes, if any
mov eax, dst ; returned address
ifdef _STDCALL_
ret 2*DPSIZE ; _stdcall return
else
ret ; _cdecl return
endif
_docat endp
end
|