diff options
Diffstat (limited to 'private/crt32/string/i386/memset.asm')
-rw-r--r-- | private/crt32/string/i386/memset.asm | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/private/crt32/string/i386/memset.asm b/private/crt32/string/i386/memset.asm new file mode 100644 index 000000000..6a6f2ca58 --- /dev/null +++ b/private/crt32/string/i386/memset.asm @@ -0,0 +1,127 @@ + page ,132 + title memset - set sections of memory all to one byte +;*** +;memset.asm - set a section of memory to all one byte +; +; Copyright (c) 1985-1991, Microsoft Corporation. All rights reserved. +; +;Purpose: +; contains the memset() routine +; +;Revision History: +; 05-07-84 RN initial version +; 06-30-87 SKS faster algorithm +; 05-17-88 SJM Add model-independent (large model) ifdef +; 08-04-88 SJM convert to cruntime/ add 32-bit support +; 08-19-88 JCR Enable word alignment code for all models/CPUs, +; Some code improvement +; 10-25-88 JCR General cleanup for 386-only code +; 10-27-88 JCR More optimization (dword alignment, no ebx usage, etc) +; 03-23-90 GJF Changed to _stdcall. Also, fixed the copyright. +; 05-10-91 GJF Back to _cdecl, sigh... +; +;******************************************************************************* + + .xlist + include cruntime.inc + .list + +page +;*** +;char *memset(dst, val, count) - sets "count" bytes at "dst" to "val" +; +;Purpose: +; Sets the first "count" bytes of the memory starting +; at "dst" to the character value "val". +; +; Algorithm: +; char * +; memset (dst, val, count) +; char *dst; +; char val; +; unsigned int count; +; { +; char *start = dst; +; +; while (count--) +; *dst++ = val; +; return(start); +; } +; +;Entry: +; char *dst - pointer to memory to fill with val +; char val - value to put in dst bytes +; int count - number of bytes of dst to fill +; +;Exit: +; returns dst, with filled bytes +; +;Uses: +; +;Exceptions: +; +;******************************************************************************* + + CODESEG + + public memset +memset proc \ + uses edi, \ + dst:ptr byte, \ + value:byte, \ + count:IWORD + + mov ecx,[count] ; cx = count + jecxz short toend ; if no work to do + + ; set all 4 bytes of eax to [value] + mov al,[value] ; the byte value to be stored + mov ah,al ; store it as a word + mov edx,eax ; lo 16 bits dx=ax=val/val + ror eax,16 ; move val/val to hi 16-bits + mov ax,dx ; eax = all 4 bytes = [value] + +; Align address on dword boundary + + mov edi,[dst] ; di = dest pointer + mov edx,edi ; dx = di = *dst + neg edx + and edx,(ISIZE-1) ; dx = # bytes before dword boundary + jz short dwords ; jump if address already aligned + + cmp ecx,edx ; count >= # leading bytes?? + jb short tail ; nope, just move ecx bytes + + sub ecx,edx ; cx = adjusted count (for later) + xchg ecx,edx ; cx = leading byte count / dx = adjusted count + rep stosb ; store leading bytes + mov ecx,edx ; cx = count of remaining bytes + ;jecxz short toend ; jump out if nothing left to do + +; Move dword-sized blocks + +dwords: + mov edx,ecx ; save original count + shr ecx,ISHIFT ; cx = dword count + rep stos IWORD ptr [edi] ; fill 'em up + mov ecx,edx ; retrieve original byte count + +; Move remaining bytes + +tail: ; store remaining 1,2, or 3 bytes + and ecx,(ISIZE-1) ; get byte count + rep stosb ; store remaining bytes, if necessary + +; Done + +toend: + mov eax,[dst] ; return dest pointer + +ifdef _STDCALL_ + ret DPSIZE + 2*ISIZE ; _stdcall return +else + ret ; _cdecl return +endif + +memset endp + end |