home *** CD-ROM | disk | FTP | other *** search
/ Graphics Programming Black Book (Special Edition) / BlackBook.bin / disk1 / source / chapter8 / l8-3.asm < prev    next >
Assembly Source File  |  1997-06-18  |  3KB  |  59 lines

  1. ; Typically optimized assembly language version of FindIDAverage.
  2.           
  3. SearchedForID   equ     4       ;passed parameter offsets in the
  4. BlockPointer    equ     6       ; stack frame (skip over pushed BP
  5.                                 ; and the return address)
  6. NextBlock       equ     0       ;field offsets in struct BlockHeader
  7. BlockCount      equ     2
  8. BLOCK_HEADER_SIZE equ   4       ;# of bytes in struct BlockHeader
  9. ID              equ     0       ;struct DataElement field offsets
  10. Value           equ     2
  11. DATA_ELEMENT_SIZE equ   4       ;# of bytes in struct DataElement
  12.  
  13.         .model  small   
  14.         .code
  15.         public  _FindIDAverage
  16. _FindIDAverage  proc    near
  17.         push    bp              ;save caller's stack frame
  18.         mov     bp,sp           ;point to our stack frame
  19.         push    di              ;preserve C register variables
  20.         push    si
  21.         sub     dx,dx           ;IDMatchSum = 0
  22.         mov     bx,dx           ;IDMatchCount = 0
  23.         mov     si,[bp+BlockPointer]    ;pointer to first block
  24.         mov     ax,[bp+SearchedForID]   ;ID we're looking for
  25. ; Search through all of the linked blocks until the last block
  26. ; (marked with a NULL pointer to the next block) has been searched.
  27. BlockLoop:
  28. ; Point to the first DataElement entry within this block.
  29.         lea     di,[si+BLOCK_HEADER_SIZE]
  30. ; Search through all the DataElement entries within this block
  31. ; and accumulate data from all that match the desired ID.
  32.         mov     cx,[si+BlockCount]
  33.         jcxz    DoNextBlock     ;no data in this block
  34. IntraBlockLoop:
  35.         cmp     [di+ID],ax      ;do we have an ID match?
  36.         jnz     NoMatch         ;no match
  37.         inc     bx              ;we have a match; IDMatchCount++;
  38.         add     dx,[di+Value]   ;IDMatchSum += DataPointer->Value;
  39. NoMatch:
  40.         add     di,DATA_ELEMENT_SIZE ;point to the next element
  41.         loop    IntraBlockLoop
  42. ; Point to the next block and continue if that pointer isn't NULL.
  43. DoNextBlock:
  44.         mov     si,[si+NextBlock] ;get pointer to the next block
  45.         and     si,si           ;is it a NULL pointer?
  46.         jnz     BlockLoop       ;no, continue
  47. ; Calculate the average of all matches.
  48.         sub     ax,ax           ;assume we found no matches
  49.         and     bx,bx
  50.         jz      Done            ;we didn't find any matches, return 0
  51.         xchg    ax,dx           ;prepare for division
  52.         div     bx              ;return IDMatchSum / IDMatchCount
  53. Done:   pop     si              ;restore C register variables
  54.         pop     di
  55.         pop     bp              ;restore caller's stack frame
  56.         ret     
  57. _FindIDAverage  ENDP
  58.         end
  59.