1/* 2 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 * 5 * Copyright 2001, Travis Geiselbrecht. All rights reserved. 6 * Distributed under the terms of the NewOS License. 7*/ 8 9 10#include <asm_defs.h> 11 12 13.align 4 14FUNCTION(memcpy): 15 pushl %esi 16 pushl %edi 17 movl 12(%esp),%edi /* dest */ 18 movl %edi,%eax /* save dest ptr as return address */ 19 movl 16(%esp),%esi /* source */ 20 movl 20(%esp),%ecx /* count */ 21 22 /* move by words */ 23 // TODO: The addresses might not be aligned! 24 cld 25 shrl $2,%ecx 26 rep 27 movsl 28 29 /* move any remaining data by bytes */ 30 movl 20(%esp),%ecx 31 andl $3,%ecx 32 rep 33 movsb 34 35 popl %edi 36 popl %esi 37 ret 38FUNCTION_END(memcpy) 39SYMBOL(memcpy_end): 40 41 42/* void *memset(void *dest, int value, size_t length); */ 43.align 4 44FUNCTION(memset): 45 push %ebp 46 mov %esp, %ebp 47 48 // %eax, %ecx, and %edx are scratch registers -- we only have to save %edi 49 push %edi 50 51 // get the parameters 52 mov 16(%ebp), %ecx 53 mov 12(%ebp), %eax 54 mov 8(%ebp), %edi 55 56 // When touching less than 12 bytes, we just do it bytewise. We might be 57 // able to process one or two lwords lwordwise, but the additional overhead 58 // isn't worth it. 59 cmp $12, %ecx 60 jl 2f 61 62 // buffer address lword-aligned? 63 mov %edi, %edx 64 and $0x3, %edx 65 jz 1f 66 67 // the buffer is unaligned -- copy the first bytes bytewise 68 mov $4, %ecx 69 sub %edx, %ecx 70 rep stosb 71 72 mov 16(%ebp), %ecx 73 sub $4, %ecx 74 add %edx, %ecx 75 761: // lwordwise 77 // prepare %eax -- the low byte must be copied to the other bytes 78 mov %al, %ah 79 mov %eax, %edx 80 shl $16, %eax 81 mov %dx, %ax 82 83 // get the unaligned remainder into %edx 84 mov %ecx, %edx 85 and $0x3, %edx 86 87 // write words 88 shr $2, %ecx 89 rep stosl 90 91 mov %edx, %ecx 92 932: // bytewise (remaining bytes) 94 rep stosb 95 96 pop %edi 97 98 // return value is the value passed in 99 mov 8(%ebp), %eax 100 101 mov %ebp, %esp 102 pop %ebp 103 ret 104FUNCTION_END(memset) 105SYMBOL(memset_end): 106 107