minix/lib/i386/string/_memmove.s
2005-04-21 14:53:53 +00:00

59 lines
1.3 KiB
ArmAsm
Executable file

! _memmove() Author: Kees J. Bot
! 2 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! void *_memmove(void *s1, const void *s2, size_t n)
! Copy a chunk of memory. Handle overlap.
!
.sect .text
.define __memmove, __memcpy
.align 16
__memmove:
push ebp
mov ebp, esp
push esi
push edi
mov edi, 8(ebp) ! String s1
mov esi, 12(ebp) ! String s2
mov ecx, 16(ebp) ! Length
mov eax, edi
sub eax, esi
cmp eax, ecx
jb downwards ! if (s2 - s1) < n then copy downwards
__memcpy:
cld ! Clear direction bit: upwards
cmp ecx, 16
jb upbyte ! Don't bother being smart with short arrays
mov eax, esi
or eax, edi
testb al, 1
jnz upbyte ! Bit 0 set, use byte copy
testb al, 2
jnz upword ! Bit 1 set, use word copy
uplword:shrd eax, ecx, 2 ! Save low 2 bits of ecx in eax
shr ecx, 2
rep
movs ! Copy longwords.
shld ecx, eax, 2 ! Restore excess count
upword: shr ecx, 1
rep
o16 movs ! Copy words
adc ecx, ecx ! One more byte?
upbyte: rep
movsb ! Copy bytes
done: mov eax, 8(ebp) ! Absolutely noone cares about this value
pop edi
pop esi
pop ebp
ret
! Handle bad overlap by copying downwards, don't bother to do word copies.
downwards:
std ! Set direction bit: downwards
lea esi, -1(esi)(ecx*1)
lea edi, -1(edi)(ecx*1)
rep
movsb ! Copy bytes
cld
jmp done