; Autre version optimisée en langage Assembleur de FindIDAverage ; qui demande d'organiser les données en deux tableaux et non en un tableau ; de structures de deux valeurs. Ce qui permet d'utiliser ; REP SCASW pour rechercher ID SearchedForID equ 4 ;offsets des paramètres passés dans BlockPointer equ 6 ;la stack frame (saute BP empilé ;et l'adresse de retour) NextBlock equ 0 ;offsets du champ dans BlockHeader BlockCount equ 2 BLOCK_HEADER_SIZE equ 4 ;nombre d'octets dans BlockHeader .model small .code public _FindIDAverage2 _FindIDAverage2 proc near push bp ;sauve la stack frame de l'appelant mov bp,sp ;pointe sur notre stack frame push di ;préserve les variables de registre C push si mov di,ds ;prepare SCASW mov es,di cld mov si,[bp+BlockPointer] ;pointeur sur le premier ;bloc mov ax,[bp+SearchedForID] ;ID recherché sub dx,dx ;IDMatchSum = 0 mov bp,dx ;IDMatchCount = 0 ;***La stack frame n'est plus disponible*** ; Recherche tous les blocs jusqu'à ce que le dernier bloc ; (celui dont le pointeur sur le prochain bloc est NULL) soit utilisé. BlockLoop: ; Recherche toutes les entrées DataElement du bloc ; et additionne les données de toutes les correspondances avec l'ID recherché. mov cx,[si+BlockCount] jcxz DoNextBlock ;saute ce bloc s'il n'y a pas de ;données ;à rechercher mov bx,cx ;nous utiliserons BX pour pointer sur ;la valeur de l'entrée correspondante shl bx,1 ;s'il y a une correspondance avec ID ;(BX indique la longueur en octets ;du tableau ID) ; Pointe sur la première entrée DataElement dans le bloc. lea di,[si+BLOCK_HEADER_SIZE] IntraBlockLoop: repnz scasw ;recherche l'ID jnz DoNextBlock ;aucune correspondance, le bloc est ;terminé inc bp ;nous avons une correspondance; ; IDMatchCount++; add dx,[di+bx-2];IDMatchSum += DataPointer->Value and cx,cx ;y a-t-il encore des données ;à rechercher ? jnz IntraBlockLoop ;oui ;Pointe sur le prochain octet et continue si le pointeur n'est pas NULL. DoNextBlock: mov si,[si+NextBlock] ;récupère le pointeur sur le ;prochain bloc and si,si ;le pointeur est-il NULL? jnz BlockLoop ;non, continuons ;Calcule la moyenne de toutes les correspondances. sub ax,ax ;suppose que nous n'avons pas trouvé ;de correspondance and bp,bp jz Done ;nous n'avons pas trouvé ;de correspondance ;retourne 0 xchg ax,dx ;prépare la division div bp ;retourne IDMatchSum / IDMatchCount Done: pop si ;restaure les variables de registre C pop di pop bp ;restaure la stack frame de l'appelant ret _FindIDAverage2 ENDP end