Можно ещё добавить варианты, используемые в других программах.
Для заполнения области памяти байтами с определённым значением(в том числе нулевым) обычно используется
memset.
Вот эта функция в
Tiny C Compiler http://websvn.kolibrios.org/filedetails ... memset.asm Code: Select all
format ELF
section '.text' executable
public memset
memset:
push edi
mov edi,[esp+8]
mov eax,[esp+12]
mov ecx,[esp+16]
jecxz .no_set
cld
rep stosb
.no_set:
mov eax, [esp+8]
pop edi
ret
А вот она же в программе
graph http://websvn.kolibrios.org/filedetails ... memset.asm Code: Select all
format MS COFF
section '.text' code readable executable
public _memset
_memset:
push edi
mov edi, [esp+8]
mov al, [esp+12]
mov ecx, [esp+16]
rep stosb
pop edi
ret
Я же в своей
libc использую такой вариант
Code: Select all
GLOBAL _memset
SECTION .text
;**********************************************************************************
_memset: ;//////////////////////////////////////////////////////////////////////////
;**********************************************************************************
%define ptr [esp + 4 +1*4] ; Pointer to block of memory to fill
%define value [esp + 8 +1*4] ; Value to be set
%define num [esp + 12 +1*4] ; Number of bytes to set to value
DEBUG.PRINT.LINE "memset start"
push edi
mov eax, value
mov edx, num
mov edi, ptr
mov ecx, eax
mov ah, al
mov ch, cl
shl ecx, 16
or eax, ecx
mov ecx, edx
shr ecx, 2
and edx, 3
rep stosd
mov ecx, edx
rep stosb
mov eax, ptr
pop edi
DEBUG.PRINT.LINE "memset finish"
ret
%undef ptr
%undef value
%undef num
Вот функция
FillChar из
RTL Delphi7Code: Select all
{ ->EAX Pointer to destination }
{ EDX count }
{ CL value }
PUSH EDI
MOV EDI,EAX { Point EDI to destination }
MOV CH,CL { Fill EAX with value repeated 4 times }
MOV EAX,ECX
SHL EAX,16
MOV AX,CX
MOV ECX,EDX
SAR ECX,2
JS @@exit
REP STOSD { Fill count DIV 4 dwords }
MOV ECX,EDX
AND ECX,3
REP STOSB { Fill count MOD 4 bytes }
@@exit:
POP EDI
Вот
memset от микрософта(
CRT Microsoft Visual C++ 6.0)
Code: Select all
public memset
memset proc
mov edx,[esp + 0ch] ; edx = "count"
mov ecx,[esp + 4] ; ecx points to "dst"
test edx,edx ; 0?
jz short toend ; if so, nothing to do
xor eax,eax
mov al,[esp + 8] ; the byte "value" to be stored
; Align address on dword boundary
push edi ; preserve edi
mov edi,ecx ; edi = dest pointer
cmp edx,4 ; if it's less then 4 bytes
jb tail ; tail needs edi and edx to be initialized
neg ecx
and ecx,3 ; ecx = # bytes before dword boundary
jz short dwords ; jump if address already aligned
sub edx,ecx ; edx = adjusted count (for later)
adjust_loop:
mov [edi],al
inc edi
dec ecx
jnz adjust_loop
dwords:
; set all 4 bytes of eax to [value]
mov ecx,eax ; ecx=0/0/0/value
shl eax,8 ; eax=0/0/value/0
add eax,ecx ; eax=0/0val/val
mov ecx,eax ; ecx=0/0/val/val
shl eax,10h ; eax=val/val/0/0
add eax,ecx ; eax = all 4 bytes = [value]
; Set dword-sized blocks
mov ecx,edx ; move original count to ecx
and edx,3 ; prepare in edx byte count (for tail loop)
shr ecx,2 ; adjust ecx to be dword count
jz tail ; jump if it was less then 4 bytes
rep stosd
main_loop_tail:
test edx,edx ; if there is no tail bytes,
jz finish ; we finish, and it's time to leave
; Set remaining bytes
tail:
mov [edi],al ; set remaining bytes
inc edi
dec edx ; if there is some more bytes
jnz tail ; continue to fill them
; Done
finish:
mov eax,[esp + 8] ; return dest pointer
pop edi ; restore edi
ret
toend:
mov eax,[esp + 4] ; return dest pointer
ret
memset endp
Если кто-то интересовался проектом
Ziron http://codeziron.com/index.php то там в
memutils используется
memFill — слегка изменённый вариант функции для моей
libc(см. выше)
Code: Select all
//******************************************************//
// //
// Ziron Run Time Library //
// Ziron Memory Utils (memutils.zir) //
// //
// Copyright (c) 2013-####, OverHertz OOD //
// //
//******************************************************//
#ifdef BITS == 32:
#set frame off;
/*
/ Fill block of memory with specified value
/ $buf -- Pointer to block of memory to fill
/ $len -- Number of bytes to set to value
/ $ch_ -- Value to be set
*/
inline function m_memFill($buf, $len, $_ch) {
// Copyright (c) 0CodErr, KolibriOS team
using(edi) {
eax = 0;
al = $_ch;
edx = $len;
edi = $buf;
push edi
ecx = eax;
ah = al;
ch = cl;
ecx << 16;
eax |= ecx;
ecx = edx;
ecx >> 2;
edx &= 3;
rep stosd;
ecx = edx;
rep stosb;
pop eax
}
$return eax;
}
function memFill(char* buf; dword len; char ch_) {
eax = m_memFill(buf, len, ch_);
}