|  | /*	$OpenBSD: memset.S,v 1.3 2005/08/07 11:30:38 espie Exp $ */ | 
|  | /* | 
|  | * Written by J.T. Conklin <jtc@netbsd.org>. | 
|  | * Public domain. | 
|  | */ | 
|  |  | 
|  | #include <machine/asm.h> | 
|  |  | 
|  | ENTRY(memset) | 
|  | pushl	%edi | 
|  | pushl	%ebx | 
|  | movl	12(%esp),%edi | 
|  | movzbl	16(%esp),%eax		/* unsigned char, zero extend */ | 
|  | movl	20(%esp),%ecx | 
|  | pushl	%edi			/* push address of buffer */ | 
|  |  | 
|  | cld				/* set fill direction forward */ | 
|  |  | 
|  | /* | 
|  | * if the string is too short, it's really not worth the overhead | 
|  | * of aligning to word boundries, etc.  So we jump to a plain | 
|  | * unaligned set. | 
|  | */ | 
|  | cmpl	$0x0f,%ecx | 
|  | jle	L1 | 
|  |  | 
|  | movb	%al,%ah			/* copy char to all bytes in word */ | 
|  | movl	%eax,%edx | 
|  | sall	$16,%eax | 
|  | orl	%edx,%eax | 
|  |  | 
|  | movl	%edi,%edx		/* compute misalignment */ | 
|  | negl	%edx | 
|  | andl	$3,%edx | 
|  | movl	%ecx,%ebx | 
|  | subl	%edx,%ebx | 
|  |  | 
|  | movl	%edx,%ecx		/* set until word aligned */ | 
|  | rep | 
|  | stosb | 
|  |  | 
|  | movl	%ebx,%ecx | 
|  | shrl	$2,%ecx			/* set by words */ | 
|  | rep | 
|  | stosl | 
|  |  | 
|  | movl	%ebx,%ecx		/* set remainder by bytes */ | 
|  | andl	$3,%ecx | 
|  | L1:	rep | 
|  | stosb | 
|  |  | 
|  | popl	%eax			/* pop address of buffer */ | 
|  | popl	%ebx | 
|  | popl	%edi | 
|  | ret |