News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

fast zeromem algo

Started by NightWare, June 08, 2007, 02:53:28 AM

Previous topic - Next topic

NightWare

hi all,

i wasn't on the net during several month... but i've never stop to code...

i don't know if someone has posted a similar algo previously... i haven't the time to read all the topic...

so here the algo, it's sse, but you don't need to align your data with this algo...
(i know... the comments are in french again... it must be a malediction...
and i use my own calling convention, but it's easy to transform it in classic call...)


ALIGN 16
;
; effacer un bloc memoire (en le remplissant de 0)
; note : le bloc mémoire n'a pas besoin d'être aligné sur 16 octets, et XMM0 est modifié
;
; Réceptionne :
; eax = taille à éffacer en octets
; esi = adresse du bloc de destination
;
; Retourne :
; rien
;
; syntaxe :
; mov eax,Size
; mov esi,StartingAddress
; call Sse_ZeroMem_UnAligned
;
Sse_ZeroMem_UnAligned PROC
push ebx ;; empiler ebx
push ecx ;; empiler ecx

; premièrement on va s'assurer que la taille minimale est atteinte, sinon on va directement traiter les dwords
xor ebx,ebx ;; effacer ebx (ca doit être fait ici, pour que tout fonctionne normalement)
cmp eax,00000000000000000000000000001111b ;; comparer eax à 15
jbe Label09 ;; si c'est inférieur ou égal, aller Label09


;
; ici, on s'occupe de la partie non alignée
;
mov ecx,esi ;; copier l'adresse de départ dans ecx
and ecx,00000000000000000000000000001111b ;; enlever les OWORDs en ecx
jz Label05 ;; si ecx est égal à zéro (c'est déjà aligné), aller Label05
mov ebx,00000000000000000000000000010000b ;; sinon, placer 16 (ben oui, ici il faut tenir compte du 0 qui ne sera pas traité) dans ebx
sub ebx,ecx ;; enlever ecx à ebx
sub eax,ebx ;; enlever ebx (la partie non alignée) à eax (la taille originelle)
; ici on traite les octets du début (on commence par les octets, pour bénéficier d'un meilleur alignement avec les dwords)
Label01: mov ecx,ebx ;; placer la taille à copier dans ecx
and ecx,00000000000000000000000000000011b ;; ne conserver que les bits octets en ecx
jz Label03 ;; si ecx est égal à 0, aller Label03
add esi,ecx ;; on ajoute ecx à esi
neg ecx ;; inverser ecx
Label02: mov BYTE PTR [esi+ecx],0 ;; placer 0 en esi+ecx
inc ecx ;; on ajoute 1 à ecx (notre pas de boucle)
jnz Label02 ;; tant que ecx est différent de 0, aller Label02
; ici on traite les dwords du début
Label03: mov ecx,ebx ;; placer la taille à copier dans ecx
and ecx,00000000000000000000000000001100b ;; ne conserver que les bits dwords en ecx
jz Label05 ;; si ecx est égal à 0, aller Label05
add esi,ecx ;; on ajoute ecx à esi
neg ecx ;; inverser ecx
Label04: mov DWORD PTR [esi+ecx],0 ;; placer 0 en esi+ecx
add ecx,4 ;; on ajoute 4 à ecx (notre pas de boucle)
jnz Label04 ;; tant que ecx est différent de 0, aller Label04


;
; ici, c'est aligné alors on traite les 4x owords
;
Label05: mov ecx,eax ;; placer la taille à copier dans ecx
and ecx,11111111111111111111111111000000b ;; ne conserver que les bits 4x owords en ecx
jz Label07 ;; si ecx est égal à 0, aller Label07
add esi,ecx ;; on ajoute ecx à esi
neg ecx ;; inverser ecx
nop ;; alignement nécessaire pour un meilleur rendement
xorps XMM0,XMM0 ;; effacer XMM0
Label06: movaps OWORD PTR[esi+ecx],XMM0 ;; placer 0 en esi+ecx
movaps OWORD PTR[esi+ecx+16],XMM0 ;; placer 0 en esi+ecx+16
movaps OWORD PTR[esi+ecx+32],XMM0 ;; placer 0 en esi+ecx+32
movaps OWORD PTR[esi+ecx+48],XMM0 ;; placer 0 en esi+ecx+48
add ecx,64 ;; on ajoute 64 à ecx (notre pas de boucle)
jnz Label06 ;; tant que ecx est différent de 0, aller Label06

; ici, on traite les owords
Label07: mov ecx,eax ;; placer la taille à copier dans ecx
and ecx,00000000000000000000000000110000b ;; ne conserver que les bits owords en ecx
jz Label09 ;; si ecx est égal à 0, aller Label09
add esi,ecx ;; on ajoute ecx à esi
neg ecx ;; inverser ecx
xorps XMM0,XMM0 ;; effacer XMM0
Label08: movaps OWORD PTR[esi+ecx],XMM0 ;; placer 0 en esi+ecx
add ecx,16 ;; on ajoute 16 à ecx (notre pas de boucle)
jnz Label08 ;; tant que ecx est différent de 0, aller Label08

; ici, on traite les dwords
Label09: mov ecx,eax ;; placer la taille à copier dans ecx
and ecx,00000000000000000000000000001100b ;; ne conserver que les bits dwords en ecx
jz Label11 ;; si ecx est égal à 0, aller Label11
add esi,ecx ;; on ajoute ecx à esi
neg ecx ;; inverser ecx
Label10: mov DWORD PTR [esi+ecx],0 ;; placer 0 en esi+ecx
add ecx,4 ;; on ajoute 4 à ecx (notre pas de boucle)
jnz Label10 ;; tant que ecx est différent de 0, aller Label10

; ici, on traite les octets
Label11: mov ecx,eax ;; placer la taille à copier dans ecx
and ecx,00000000000000000000000000000011b ;; ne conserver que les bits octets en ecx
jz Label13 ;; si ecx est égal à 0, aller Label13
add esi,ecx ;; on ajoute ecx à esi
neg ecx ;; inverser ecx
Label12: mov BYTE PTR [esi+ecx],0 ;; placer 0 en esi+ecx
inc ecx ;; on ajoute 1 à ecx (notre pas de boucle)
jnz Label12 ;; tant que ecx est différent de 0, aller Label12

; enfin, on corrige les valeurs utilisées pour retrouver les valeurs originelles
Label13: add eax,ebx ;; rajouter ebx à eax
sub esi,eax ;; soustraire la taille à esi (pour retrouver l'adresse originelle)

pop ecx ;; désempiler ecx
pop ebx ;; désempiler ebx
ret ;; retourner (sortir de la procédure)
Sse_ZeroMem_UnAligned ENDP


jdoe, my apologies again...