133 lines
3.8 KiB
NASM
133 lines
3.8 KiB
NASM
;*******************************************************************************
|
|
;memset.asm - set a section of memory to all one byte
|
|
;
|
|
; Copyright (c) Microsoft Corporation. All rights reserved.
|
|
;
|
|
;Purpose:
|
|
; contains the memset() routine
|
|
;
|
|
;*******************************************************************************
|
|
|
|
.code
|
|
|
|
;***
|
|
;char *memset(dst, value, count) - sets "count" bytes at "dst" to "value"
|
|
;
|
|
;Purpose:
|
|
; Sets the first "count" bytes of the memory starting
|
|
; at "dst" to the character value "value".
|
|
;
|
|
; Algorithm:
|
|
; char *
|
|
; memset (dst, value, count)
|
|
; char *dst;
|
|
; char value;
|
|
; unsigned int count;
|
|
; {
|
|
; char *start = dst;
|
|
;
|
|
; while (count--)
|
|
; *dst++ = value;
|
|
; return(start);
|
|
; }
|
|
;
|
|
;Entry:
|
|
; char *dst - pointer to memory to fill with value
|
|
; char value - value to put in dst bytes
|
|
; int count - number of bytes of dst to fill
|
|
;
|
|
;Exit:
|
|
; returns dst, with filled bytes
|
|
;
|
|
;Uses:
|
|
;
|
|
;Exceptions:
|
|
;
|
|
;*******************************************************************************
|
|
|
|
public memset
|
|
memset proc
|
|
;
|
|
; On entry: rcx=dest, rdx=value, r8=count
|
|
;
|
|
test r8,r8 ; 0?
|
|
jz short toend ; if so, nothing to do
|
|
|
|
xor rax,rax
|
|
mov al,dl ; al = value
|
|
mov rdx,r8 ; rdx = "count"
|
|
mov r8,rcx ; scroll away dest for return
|
|
|
|
; Align address on qword boundary
|
|
|
|
push rdi ; preserve rdi
|
|
mov rdi,rcx ; rdi = dest pointer
|
|
|
|
cmp rdx,8 ; if it's less then 8 bytes
|
|
jb tail ; tail needs rdi and rdx to be initialized
|
|
|
|
neg rcx
|
|
and rcx,7 ; ecx = # bytes before dword boundary
|
|
jz short qwords ; jump if address already aligned
|
|
|
|
sub rdx,rcx ; edx = adjusted count (for later)
|
|
adjust_loop:
|
|
mov [rdi],al
|
|
add rdi,1
|
|
sub rcx,1
|
|
jnz adjust_loop
|
|
|
|
qwords:
|
|
; set all 8 bytes of eax to [value]
|
|
mov rcx,rax ; rcx=0/0/0/0/0/0/0/value
|
|
shl rax,8 ; rax=0/0/0/0/0/0/value/0
|
|
|
|
add rax,rcx ; rax=0/0/0/0/0/0/0/val/val
|
|
|
|
mov rcx,rax ; rcx=0/0/0/0/0/0/0/val/val
|
|
|
|
shl rax,10h ; rax=0/0/0/0/val/val/0/0
|
|
|
|
add rax,rcx ; rax = all 4 bytes = [value]
|
|
|
|
mov rcx,rax ; rcx = 0/0/0/0/val/val/val/val
|
|
shl rax,20h ; rax = val/val/val/val/0/0/0/0/
|
|
|
|
add rax,rcx ; rax = val/val/val/val/val/val/val/val
|
|
|
|
|
|
; Set qword-sized blocks
|
|
mov rcx,rdx ; move original count to ecx
|
|
and rdx,7 ; prepare in edx byte count (for tail loop)
|
|
shr rcx,3 ; adjust ecx to be dword count
|
|
jz tail ; jump if it was less then 4 bytes
|
|
|
|
rep stosq
|
|
main_loop_tail:
|
|
test rdx,rdx ; if there is no tail bytes,
|
|
jz finish ; we finish, and it's time to leave
|
|
; Set remaining bytes
|
|
|
|
tail:
|
|
mov [rdi],al ; set remaining bytes
|
|
add rdi,1
|
|
|
|
sub rdx,1 ; if there is some more bytes
|
|
jnz tail ; continue to fill them
|
|
|
|
; Done
|
|
finish:
|
|
mov rax,r8 ; return dest pointer
|
|
pop rdi ; restore edi
|
|
|
|
ret
|
|
|
|
toend:
|
|
mov rax,rcx ; return dest pointer
|
|
|
|
ret
|
|
|
|
memset endp
|
|
|
|
end
|