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
|
page ,132
title STRECPY
COMMENT $
Author: Leslie Satenstein
A form of strcpy() where the result returned is the
nul terminating character of the first argument. In many cases
this function is move efficient than the equivalent
strcpy, followed by strcat.
The assembler code does a strlen followed by a memcpy,
and makes use of the special string move instructions
intrinsic to the intel 8088, 80186, 80286, '386 and '486s.
Use as: strecpy(strecpy(target,"first part"),"Second part");
in place of
strcat(strcpy(target,"first part"),"Second part");
One of the ways the C code appears is:
char *strecpy(char *target,const char *src)
{
return target+strlen(strcpy(target,src));
}
Another way is to do your own looping:
char *strecpy(char *target,const char *src)
{
char *cpt,*cps; /* many compilers optimise better
* when local pointers are declared
* (locals can be assigned registers)
*/
cpt=target-1;
cps=src-1;
do
{
*++cpt = *++src; /* copy first, ask questions later */
} while(*cpt!='\0');
return cpt;
}
$
; Requires MASM 5.1 or later or equivalent
;
; Assemble with: MASM /Mx /z ...
; TASM /jMASM /mx /z ...
% .MODEL memodel,C ;Add model support via command
;line macros, e.g.
;MASM /Dmemodel=LARGE,
;MASM /Dmemodel=SMALL, etc.
PUBLIC STRECPY
.DATA
.CODE
if @DataSize
strecpy proc uses si di ds,target:FAR ptr byte,src:FAR ptr byte
les di,src ; load es:di with src
mov si,di ; put copy to bx:si
mov bx,es
else
strecpy proc uses si di,target:NEAR ptr byte,src:NEAR ptr byte
mov di,ds ; make es same as ds
mov es,di
mov di,src
mov si,di ; put copy to es:si
endif
xor ax,ax ; scan for the nul at end of string
mov cx,-1
repne scasb
not cx ; cx = strlen(src)+1 ;
if @Datasize
les di,target ; this is where copy is to begin
mov dx,es ; dx has segment, di has offset to target
mov ds,bx ; ds:si have pointer to src
else
mov di,target ; this is where copy is to begin
endif
test di,1 ; if we are on odd address, do one byte move
jz on_even
movsb ; now, prepare to move words at a
dec cx ;time to target
on_even:
shr cx,1 ; carry flag has remainder after divide by 2
rep movsw ; move this many words
jnc fini ; if no carry, we are finished
movsb
fini:
xchg di,ax ; set up return value, dx has seg value
dec ax ; backup to the nul character
ret
strecpy endp
end
|