MEMCPY ET ZEROMEMORY

Messages postés
168
Date d'inscription
mardi 31 décembre 2002
Statut
Membre
Dernière intervention
21 avril 2005
- - Dernière réponse : zeratul67
Messages postés
98
Date d'inscription
mardi 9 avril 2002
Statut
Membre
Dernière intervention
11 mai 2008
- 26 oct. 2006 à 22:27
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/11100-memcpy-et-zeromemory

Afficher la suite 
zeratul67
Messages postés
98
Date d'inscription
mardi 9 avril 2002
Statut
Membre
Dernière intervention
11 mai 2008
-
Voici le code assembleur généré par VS, à titre d'info, suru n cas bien simple :

for (int i = 0; i < 255; i++)
0040101E mov dword ptr [i],0
00401028 jmp WinMain+39h (401039h)
0040102A mov eax,dword ptr [i]
00401030 add eax,1
00401033 mov dword ptr [i],eax
00401039 cmp dword ptr [i],0FFh
00401043 jge WinMain+55h (401055h)
tab[i] = 0;
00401045 mov eax,dword ptr [i]
0040104B mov byte ptr tab[eax],0
00401053 jmp WinMain+2Ah (40102Ah)

ZeroMemory(tab, 255);
00401055 push 0FFh
0040105A push 0
0040105C lea eax,[tab]
00401062 push eax
00401063 call memset (4010B0h)
00401068 add esp,0Ch

Et voici le code de Memset

;***
;memset.asm - set a section of memory to all one byte
;
; Copyright (c) Microsoft Corporation. All rights reserved.
;
;Purpose:
; contains the memset() routine
;
;*******************************************************************************

.xlist
include cruntime.inc
.list

page
;***
;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:
;
;*******************************************************************************

CODESEG

public memset
memset proc

.FPO ( 0, 3, 0, 0, 0, 0 )

mov edx,[esp + 0ch] ; edx = "count"
004010B0 mov edx,dword ptr [esp+0Ch]
mov ecx,[esp + 4] ; ecx points to "dst"
004010B4 mov ecx,dword ptr [esp+4]

test edx,edx ; 0?
004010B8 test edx,edx
jz short toend ; if so, nothing to do
004010BA je toend (40110Bh)

xor eax,eax
004010BC xor eax,eax
mov al,[esp + 8] ; the byte "value" to be stored
004010BE mov al,byte ptr [esp+8]


; Align address on dword boundary

push edi ; preserve edi
004010C2 push edi
mov edi,ecx ; edi = dest pointer
004010C3 mov edi,ecx

cmp edx,4 ; if it's less then 4 bytes
004010C5 cmp edx,4
jb tail ; tail needs edi and edx to be initialized
004010C8 jb tail (4010FBh)

neg ecx
004010CA neg ecx
and ecx,3 ; ecx = # bytes before dword boundary
004010CC and ecx,3
jz short dwords ; jump if address already aligned
004010CF je dwords (4010DDh)

sub edx,ecx ; edx = adjusted count (for later)
004010D1 sub edx,ecx
adjust_loop:
mov [edi],al
004010D3 mov byte ptr [edi],al
add edi,1
004010D5 add edi,1
sub ecx,1
004010D8 sub ecx,1
jnz adjust_loop
004010DB jne adjust_loop (4010D3h)

dwords:
; set all 4 bytes of eax to [value]
mov ecx,eax ; ecx=0/0/0/value
004010DD mov ecx,eax
shl eax,8 ; eax=0/0/value/0
004010DF shl eax,8

add eax,ecx ; eax=0/0val/val
004010E2 add eax,ecx

mov ecx,eax ; ecx=0/0/val/val
004010E4 mov ecx,eax

shl eax,10h ; eax=val/val/0/0
004010E6 shl eax,10h

add eax,ecx ; eax all 4 bytes [value]
004010E9 add eax,ecx

; Set dword-sized blocks
mov ecx,edx ; move original count to ecx
004010EB mov ecx,edx
and edx,3 ; prepare in edx byte count (for tail loop)
004010ED and edx,3
shr ecx,2 ; adjust ecx to be dword count
004010F0 shr ecx,2
jz tail ; jump if it was less then 4 bytes
004010F3 je tail (4010FBh)

rep stosd
004010F5 rep stos dword ptr [edi]
main_loop_tail:
test edx,edx ; if there is no tail bytes,
004010F7 test edx,edx
jz finish ; we finish, and it's time to leave
004010F9 je finish (401105h)
; Set remaining bytes

tail:
mov [edi],al ; set remaining bytes
004010FB mov byte ptr [edi],al
add edi,1
004010FD add edi,1

sub edx,1 ; if there is some more bytes
00401100 sub edx,1
jnz tail ; continue to fill them
00401103 jne tail (4010FBh)

; Done
finish:
mov eax,[esp + 8] ; return dest pointer
00401105 mov eax,dword ptr [esp+8]
pop edi ; restore edi
00401109 pop edi

ret
0040110A ret
omi
Messages postés
11
Date d'inscription
samedi 12 janvier 2002
Statut
Membre
Dernière intervention
22 juillet 2003
-
Ben oui mais ces fonctions seront toujours plus rapide, a longueur égales, que avec une boucle for programmez a la main quelque soit la longeur de la chaine.
Qui d'ailleur dans le programme peut etre reglé en modifiant la constante LG.
JackosKing
Messages postés
168
Date d'inscription
mardi 31 décembre 2002
Statut
Membre
Dernière intervention
21 avril 2005
-
la vitesse est fonction de la longueur du buffer a effacer...