; Version en langage Assembleur avec optimisation standard de FindIDAverage. SearchedForID equ 4 ;offsets de paramètres passés dans la BlockPointer equ 6 ;stack frame (saute BP empilé et ;l'adresse de retour) NextBlock equ 0 ;offsets des champs dans BlockHeader BlockCount equ 2 BLOCK_HEADER_SIZE equ 4 ;nombre d'octets dans BlockHeader ID equ 0 ;offsets du champ dans DataElement Value equ 2 DATA_ELEMENT_SIZE equ 4 ;nombre d'octets dans DataElement .model small .code public _FindIDAverage _FindIDAverage 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 sub dx,dx ;IDMatchSum = 0 mov bx,dx ;IDMatchCount = 0 mov si,[bp+BlockPointer] ;pointeur sur le premier ;bloc mov ax,[bp+SearchedForID] ;ID à rechercher ; Recherche tous les blocs jusqu'à ce que le dernier soit trouvé ; (celui dont le pointeur sur le bloc suivant est à NULL ). BlockLoop: ; Pointe sur la première entrée DataElement du bloc. lea di,[si+BLOCK_HEADER_SIZE] ; Recherche toutes les entrées DataElement du bloc ; et additionne toutes les données qui correspondent à l'ID recherché. mov cx,[si+BlockCount] jcxz DoNextBlock ;aucune donnée dans ce bloc IntraBlockLoop: cmp [di+ID],ax ;avons-nous une correspondance de ;l'ID? jnz NoMatch ;non inc bx ;nous avons une correspondance ;IDMatchCount++; add dx,[di+Value];IDMatchSum += DataPointer->Value NoMatch: add di,DATA_ELEMENT_SIZE ;pointe sur ;le prochain élément loop IntraBlockLoop ; Pointe sur le prochain bloc et continue si ce 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 toutes les correspondances. sub ax,ax ;suppose que nous n'avons pas trouvé ;de correspondance and bx,bx jz Done ;nous n'avons pas trouvé ;de correspondance ;retourne 0 xchg ax,dx ;prépare la division div bx ;retourne IDMatchSum / IDMatchCount Done: pop si ;restaure les variables registre C pop di pop bp ;restaure la stack frame de l'appelant ret _FindIDAverage ENDP end