summaryrefslogtreecommitdiffstats
path: root/private/crt32/string/i386/strcat.asm
blob: 9781440c19404a34a31e84dbb9ce944910405c59 (plain) (blame)
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