1 | ! _memmove() Author: Kees J. Bot
|
---|
2 | ! 2 Jan 1994
|
---|
3 | .sect .text; .sect .rom; .sect .data; .sect .bss
|
---|
4 |
|
---|
5 | ! void *_memmove(void *s1, const void *s2, size_t n)
|
---|
6 | ! Copy a chunk of memory. Handle overlap.
|
---|
7 | !
|
---|
8 | .sect .text
|
---|
9 | .define __memmove, __memcpy
|
---|
10 | .align 16
|
---|
11 | __memmove:
|
---|
12 | push ebp
|
---|
13 | mov ebp, esp
|
---|
14 | push esi
|
---|
15 | push edi
|
---|
16 | mov edi, 8(ebp) ! String s1
|
---|
17 | mov esi, 12(ebp) ! String s2
|
---|
18 | mov ecx, 16(ebp) ! Length
|
---|
19 | mov eax, edi
|
---|
20 | sub eax, esi
|
---|
21 | cmp eax, ecx
|
---|
22 | jb downwards ! if (s2 - s1) < n then copy downwards
|
---|
23 | __memcpy:
|
---|
24 | cld ! Clear direction bit: upwards
|
---|
25 | cmp ecx, 16
|
---|
26 | jb upbyte ! Don't bother being smart with short arrays
|
---|
27 | mov eax, esi
|
---|
28 | or eax, edi
|
---|
29 | testb al, 1
|
---|
30 | jnz upbyte ! Bit 0 set, use byte copy
|
---|
31 | testb al, 2
|
---|
32 | jnz upword ! Bit 1 set, use word copy
|
---|
33 | uplword:shrd eax, ecx, 2 ! Save low 2 bits of ecx in eax
|
---|
34 | shr ecx, 2
|
---|
35 | rep
|
---|
36 | movs ! Copy longwords.
|
---|
37 | shld ecx, eax, 2 ! Restore excess count
|
---|
38 | upword: shr ecx, 1
|
---|
39 | rep
|
---|
40 | o16 movs ! Copy words
|
---|
41 | adc ecx, ecx ! One more byte?
|
---|
42 | upbyte: rep
|
---|
43 | movsb ! Copy bytes
|
---|
44 | done: mov eax, 8(ebp) ! Absolutely noone cares about this value
|
---|
45 | pop edi
|
---|
46 | pop esi
|
---|
47 | pop ebp
|
---|
48 | ret
|
---|
49 |
|
---|
50 | ! Handle bad overlap by copying downwards, don't bother to do word copies.
|
---|
51 | downwards:
|
---|
52 | std ! Set direction bit: downwards
|
---|
53 | lea esi, -1(esi)(ecx*1)
|
---|
54 | lea edi, -1(edi)(ecx*1)
|
---|
55 | rep
|
---|
56 | movsb ! Copy bytes
|
---|
57 | cld
|
---|
58 | jmp done
|
---|