[9] | 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
|
---|