home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_122 / 2.ddi / CLIBSRC3.ZIP / NHEAPCHK.ASM < prev    next >
Encoding:
Assembly Source File  |  1992-06-10  |  16.1 KB  |  418 lines

  1. ;[]-----------------------------------------------------------------[]
  2. ;|      NHEAPCHK.ASM                                                 |
  3. ;[]-----------------------------------------------------------------[]
  4.  
  5. ;
  6. ;       C/C++ Run Time Library - Version 5.0
  7. ;       Copyright (c) 1987, 1992 by Borland International
  8. ;       All Rights Reserved.
  9.  
  10.         INCLUDE RULES.ASI
  11.  
  12.         LOCALS
  13.         INCLUDE _HEAP.INC
  14.  
  15. IF LPROG
  16.   EXTRADISP     equ     2         ; Allow for FAR returns when getting parms
  17.   DIST          equ     FAR
  18. ELSE
  19.   EXTRADISP     equ     0
  20.   DIST          equ     NEAR
  21. ENDIF
  22.  
  23. IF LDATA EQ false
  24.  
  25. ;-----------------------------------------------------------------------
  26. ; Memory Block Header (near heap)
  27. ;-----------------------------------------------------------------------
  28. ; Each block in the heap, whether allocated or free, has a header.
  29. ; For an allocated block, only the first two fields of the header are
  30. ; used. For a free block all eight bytes are used, thus the smallest
  31. ; possible block is the size of a free header.
  32. ;
  33. ; Field       Description
  34. ; ---------   ----------------------------------------------------------
  35. ; size        total size, in bytes, of this block (+1 if the block is in use)
  36. ; prev_real   pointer to the physically previous block in the heap
  37. ; prev_free   pointer to the logically previous free block
  38. ; next_free   pointer to the logically next free block
  39. ;
  40. ; Note that the size field is also used to indicate whether the block
  41. ; is allocated or free.  A doubly-linked queue is maintained of the
  42. ; free blocks and it is important to know that ordering of the blocks
  43. ; in this queue is logical rather than physical.  If there is only one
  44. ; free block on the heap prev_free and next_free point to itself.
  45. ;-----------------------------------------------------------------------
  46. Header          STRUC
  47. bsize           dw      ?
  48. prev_real       dw      ?
  49. prev_free       dw      ?
  50. next_free       dw      ?
  51.                 ENDS
  52.  
  53. ;-----------------------------------------------------------------------
  54. ; heapinfo structure (near heap)
  55. ;-----------------------------------------------------------------------
  56. ; Used by the heapwalk function.
  57. ; heapwalk accepts a pointer to a struct of this type.
  58. ; On entry, the pointer field contains the address of the previous
  59. ; memory block in the heap (NULL for the first call).  The next block
  60. ; in the heap is then found and its address is stored in the structure
  61. ; along with its size, in bytes, and a 'used' flag.
  62. ;-----------------------------------------------------------------------
  63. HeapInfo        STRUC
  64. hi_ptr          dw      ?
  65. hi_size         dw      ?
  66. hi_inuse        dw      ?
  67.                 ENDS
  68.  
  69. UsedHeaderSize  EQU     4
  70. FreeHeaderSize  EQU     8
  71.  
  72. ;-----------------------------------------------------------------------
  73. ; Only three variables are needed to efficiently manage the heap.
  74. ;-----------------------------------------------------------------------
  75.                 EXTRN __first:word        ;pointer to the first block
  76.                 EXTRN __last:word         ;pointer to the last block
  77.                 EXTRN __rover:word        ;pointer to an arbitrary free block
  78.  
  79.  
  80. _TEXT           SEGMENT PUBLIC 'CODE'
  81.                 ASSUME CS:_TEXT
  82.  
  83. ;-----------------------------------------------------------------------------
  84. ; C callable function which checks and verifies the heap.
  85. ; Walk through the physical heap and free block queue checking for
  86. ; bad links, adjacent free blocks, and sum the free block sizes both
  87. ; ways.  If the physical free block sum does not equal the free-block
  88. ; queue sum, there is an error.
  89. ;
  90. ; Args:                 void
  91. ; Returns:              _HEAPEMPTY, _HEAPOK, or _HEAPCORRUPT in ax
  92. ;-----------------------------------------------------------------------------
  93.                 PUBLIC  _heapcheck
  94. _heapcheck      PROC DIST
  95.                 push    si
  96.                 push    di
  97.                 push    bx
  98.                 push    cx
  99.                 push    dx
  100.  
  101.                 mov     bx,__first              ;bx = first block in heap
  102.                 or      bx,bx                   ;is it NULL?
  103.                 jz      @@EmptyHeap
  104.                 mov     si,[bx.bsize]           ;si = next block after bx
  105.                 and     si,0fffeh
  106.                 add     si,bx
  107.  
  108.                 xor     cx,cx                   ;cx = size sum of physical free blocks
  109.                 mov     dx,cx                   ;dx = size sum of free block queue
  110. @@SearchPhysicalLinks:
  111.                 test    BYTE PTR [bx.bsize],01h ;is this block used?
  112.                 jnz     @@CheckPhysicalLinks
  113.                 add     cx,[bx.bsize]           ;cx += size of this free block
  114.                 cmp     bx,[__last]             ;at the end of the heap?
  115.                 je      @@QueueCheck
  116.                 test    BYTE PTR [si.bsize],01h ;this block should be used
  117.                 jz      @@HeapCorrupt           ;Oh nooooo, Mr. Bill!
  118. @@CheckPhysicalLinks:
  119.                 cmp     bx,[__last]             ;at the end of the heap?
  120.                 je      @@QueueCheck
  121.                 cmp     si,bx                   ;check those links!
  122.                 jbe     @@HeapCorrupt
  123.                 cmp     [bx.bsize],FreeHeaderSize
  124.                 jb      @@HeapCorrupt
  125.                 cmp     si,[__first]
  126.                 jbe     @@HeapCorrupt
  127.                 cmp     si,[__last]
  128.                 ja      @@HeapCorrupt
  129.                 cmp     [si.prev_real],bx
  130.                 jne     @@HeapCorrupt
  131.                 mov     bx,si                   ;bx = next block in heap
  132.                 mov     si,[bx.bsize]           ;si = next block after bx
  133.                 and     si,0fffeh
  134.                 add     si,bx
  135.                 jmp     SHORT @@SearchPhysicalLinks
  136. @@QueueCheck:
  137.                 mov     bx,[__rover]
  138.                 or      bx,bx
  139.                 jz      @@EvaluateResults
  140. @@QueueLoop:
  141.                 mov     ax,[bx.bsize]           ;this block should be free
  142.                 test    al,01h                  ;well, is it?
  143.                 jnz     @@HeapCorrupt           ;Oh nooooo, Mr. Bill!
  144.                 add     dx,ax                   ;dx += size of this block
  145.                 cmp     bx,[__first]
  146.                 jb      @@HeapCorrupt
  147.                 cmp     bx,[__last]
  148.                 jae     @@HeapCorrupt
  149.                 mov     si,[bx.next_free]       ;si = the next free block
  150.                 cmp     si,[__rover]            ;done?
  151.                 je      @@EvaluateResults
  152.                 cmp     si,bx                   ;check those links!
  153.                 je      @@HeapCorrupt
  154.                 mov     bx,si
  155.                 jmp     SHORT @@QueueLoop
  156. @@EmptyHeap:
  157.                 mov     ax,_HEAPEMPTY
  158.                 jmp     SHORT @@AllDone
  159.  
  160. @@EvaluateResults:
  161.                 cmp     dx,cx
  162.                 jne     @@HeapCorrupt
  163. @@HeapOK:
  164.                 mov     ax,_HEAPOK
  165.                 jmp     SHORT @@AllDone
  166. @@HeapCorrupt:
  167.                 mov     ax,_HEAPCORRUPT
  168. @@AllDone:
  169.                 pop     dx
  170.                 pop     cx
  171.                 pop     bx
  172.                 pop     di
  173.                 pop     si
  174.                 ret
  175.                 ENDP
  176.  
  177. ;-----------------------------------------------------------------------------
  178. ; C callable function which checks and verifies a node on the heap.
  179. ;-----------------------------------------------------------------------------
  180. ; Args:                 node to check (stack)
  181. ; Returns:              _HEAPCORRUPT, _BADNODE, _FREEENTRY, or _USEDENTRY in ax
  182. ;-----------------------------------------------------------------------------
  183.                 PUBLIC  _heapchecknode
  184. _heapchecknode  PROC DIST
  185.                 push    si
  186.                 push    di
  187.                 push    bp
  188.  
  189.                 mov     bp,sp
  190.  
  191.                 mov     ax,[bp+8+EXTRADISP]     ;ax = node to find
  192.                 sub     ax,UsedHeaderSize
  193.  
  194.                 mov     bx,[__first]            ;bx = first block in heap
  195.                 or      bx,bx                   ;is it NULL?
  196.                 jz      @@EmptyHeap
  197.                 mov     si,[bx.bsize]           ;si = next block after bx
  198.                 and     si,0fffeh
  199.                 add     si,bx
  200.  
  201. @@SearchPhysicalLinks:
  202.                 cmp     bx,ax
  203.                 je      @@Found
  204.                 test    BYTE PTR [bx.bsize],01h ;is this block used?
  205.                 jnz     @@CheckPhysicalLinks
  206.                 cmp     bx,[__last]             ;at the end of the heap?
  207.                 je      @@NotFound
  208.                 test    BYTE PTR [si.bsize],01h ;this block should be used
  209.                 jz      @@HeapCorrupt           ;Oh nooooo, Mr. Bill!
  210. @@CheckPhysicalLinks:
  211.                 cmp     bx,[__last]             ;at the end of the heap?
  212.                 je      @@NotFound
  213.                 cmp     si,bx                   ;check those links!
  214.                 jbe     @@HeapCorrupt
  215.                 cmp     [bx.bsize],FreeHeaderSize
  216.                 jb      @@HeapCorrupt
  217.                 cmp     si,[__first]
  218.                 jbe     @@HeapCorrupt
  219.                 cmp     si,[__last]
  220.                 ja      @@HeapCorrupt
  221.                 cmp     si,bx
  222.                 jbe     @@HeapCorrupt
  223.                 cmp     [si.prev_real],bx
  224.                 jne     @@HeapCorrupt
  225.                 mov     bx,si                   ;bx = next block in heap
  226.                 mov     si,[bx.bsize]           ;si = next block after bx
  227.                 and     si,0fffeh
  228.                 add     si,bx
  229.                 jmp     SHORT @@SearchPhysicalLinks
  230. @@EmptyHeap:
  231.                 mov     ax,_HEAPEMPTY
  232.                 jmp     SHORT @@AllDone
  233. @@HeapCorrupt:
  234.                 mov     ax,_HEAPCORRUPT
  235.                 jmp     SHORT @@AllDone
  236. @@NotFound:
  237.                 mov     ax,_BADNODE
  238.                 jmp     SHORT @@AllDone
  239. @@Found:
  240.                 test    BYTE PTR [bx.bsize],01
  241.                 jnz     @@UsedEntry
  242. @@FreeEntry:
  243.                 mov     ax,_FREEENTRY
  244.                 jmp     SHORT @@AllDone
  245. @@UsedEntry:
  246.                 mov     ax,_USEDENTRY
  247. @@AllDone:
  248.                 pop     bp
  249.                 pop     di
  250.                 pop     si
  251.                 ret
  252.                 ENDP
  253.  
  254. ;-----------------------------------------------------------------------------
  255. ; C callable function which fills the free areas with a given value
  256. ;-----------------------------------------------------------------------------
  257. ; Args:                 unsigned int, fill value (stack)
  258. ; Returns:              _HEAPEMPTY, _HEAPOK, or _HEAPCORRUPT in ax
  259. ;-----------------------------------------------------------------------------
  260.                 PUBLIC  _heapfillfree
  261. _heapfillfree   PROC DIST
  262.                 push    bp
  263.                 mov     bp,sp
  264.                 mov     ax,[bp+4+EXTRADISP]
  265.  
  266.                 push    si
  267.                 push    di
  268.  
  269.                 cmp     __first,0
  270.                 je      @@EmptyHeap
  271.  
  272.                 mov     bx,__rover
  273.                 or      bx,bx
  274.                 jz      @@HeapOK
  275.                 cld
  276. @@QueueLoop:
  277.                 mov     cx,[bx.bsize]
  278.                 sub     cx,FreeHeaderSize
  279.                 shr     cx,1
  280.                 lea     di,[bx+8]
  281.                 rep
  282.                 stosw
  283.                 mov     cx,[bx.next_free]       ;cx = next free block
  284.                 cmp     cx,[__rover]            ;done?
  285.                 je      @@HeapOK
  286.                 cmp     bx,cx                   ;check links
  287.                 je      @@HeapCorrupt
  288.                 or      cx,cx
  289.                 jz      @@HeapCorrupt
  290.                 mov     bx,cx                   ;get the next free block
  291.                 jmp     SHORT @@QueueLoop
  292. @@HeapOK:
  293.                 mov     ax,_HEAPOK
  294.                 jmp     SHORT @@AllDone
  295. @@EmptyHeap:
  296.                 mov     ax,_HEAPEMPTY
  297.                 jmp     SHORT @@AllDone
  298. @@HeapCorrupt:
  299.                 mov     ax,_HEAPCORRUPT
  300. @@AllDone:
  301.                 pop     di
  302.                 pop     si
  303.                 pop     bp
  304.                 ret
  305.                 ENDP
  306.  
  307. ;-----------------------------------------------------------------------------
  308. ; C callable function which checks the free areas of the heap for a given value
  309. ;-----------------------------------------------------------------------------
  310. ; Args:                 unsigned int, fill value (stack)
  311. ; Returns:              _HEAPOK, _HEAPEMPTY, _BADVALUE, or _HEAPCORRUPT in ax
  312. ;-----------------------------------------------------------------------------
  313.                 PUBLIC  _heapcheckfree
  314. _heapcheckfree  PROC DIST
  315.                 push    bp
  316.                 mov     bp,sp
  317.                 mov     ax,[bp+4+EXTRADISP]
  318.  
  319.                 push    si
  320.                 push    di
  321.  
  322.                 cmp     __first,0
  323.                 je      @@EmptyHeap
  324.  
  325.                 mov     bx,__rover
  326.                 or      bx,bx
  327.                 jz      @@HeapOK
  328.                 cld
  329. @@QueueLoop:
  330.                 mov     cx,[bx.bsize]
  331.                 sub     cx,FreeHeaderSize
  332.                 shr     cx,1
  333.                 lea     di,[bx+8]
  334.                 repe
  335.                 scasw
  336.                 jnz     @@BadValue
  337.                 mov     cx,[bx.next_free]       ;cx = next free block
  338.                 cmp     cx,[__rover]            ;done?
  339.                 je      @@HeapOK
  340.                 cmp     bx,cx                   ;check links
  341.                 je      @@HeapCorrupt
  342.                 or      cx,cx
  343.                 jz      @@HeapCorrupt
  344.                 mov     bx,cx                   ;get the next free block
  345.                 jmp     SHORT @@QueueLoop
  346. @@HeapOK:
  347.                 mov     ax,_HEAPOK
  348.                 jmp     SHORT @@AllDone
  349. @@EmptyHeap:
  350.                 mov     ax,_HEAPEMPTY
  351.                 jmp     SHORT @@AllDone
  352. @@BadValue:
  353.                 mov     ax,_BADVALUE
  354.                 jmp     SHORT @@AllDone
  355. @@HeapCorrupt:
  356.                 mov     ax,_HEAPCORRUPT
  357. @@AllDone:
  358.                 pop     di
  359.                 pop     si
  360.                 pop     bp
  361.                 ret
  362.                 ENDP
  363.  
  364. ;-----------------------------------------------------------------------------
  365. ; C callable function to walk through the heap node by node
  366. ;-----------------------------------------------------------------------------
  367. ; Args:                 pointer to a heapinfo structure (stack)
  368. ; Returns:              _HEAPOK, _HEAPEMPTY, _HEAPEND in ax
  369. ;-----------------------------------------------------------------------------
  370.                 PUBLIC  _heapwalk
  371. _heapwalk       PROC DIST
  372.                 push    bp
  373.                 push    si
  374.  
  375.                 mov     bp,sp
  376.                 mov     bx,[bp+6+EXTRADISP]     ;bx = address of heapinfo struct
  377.                 mov     si,[bx.hi_ptr]          ;si = previous block
  378.                 or      si,si                   ;si == NULL?
  379.                 je      @@FirstBlock
  380.                 sub     si,UsedHeaderSize
  381.                 cmp     si,[__last]             ;last block?
  382.                 je      @@HeapEnd
  383. @@InnerBlock:
  384.                 add     si,[si.bsize]           ;si = next block
  385.                 and     si,0fffeh               ;strip 'used' bit
  386.                 jmp     SHORT @@SaveInfo
  387. @@FirstBlock:
  388.                 mov     si,[__first]
  389.                 or      si,si
  390.                 jz      @@HeapEmpty
  391. @@SaveInfo:
  392.                 mov     [bx.hi_ptr],si
  393.                 add     [bx.hi_ptr],UsedHeaderSize
  394.                 mov     ax,[si.bsize]
  395.                 and     ax,0fffeh               ;strip 'used' bit
  396.                 mov     [bx.hi_size],ax
  397.                 mov     ax,[si.bsize]
  398.                 and     ax,0001h                ;retrieve 'used' bit
  399.                 mov     [bx.hi_inuse],ax
  400. @@HeapOK:
  401.                 mov     ax,_HEAPOK
  402.                 jmp     SHORT @@AllDone
  403. @@HeapEmpty:
  404.                 mov     ax,_HEAPEMPTY
  405.                 jmp     SHORT @@AllDone
  406. @@HeapEnd:
  407.                 mov     ax,_HEAPEND
  408. @@AllDone:
  409.                 pop     si
  410.                 pop     bp
  411.                 ret
  412.                 ENDP
  413.                 ENDS
  414. ENDIF
  415.                 END
  416.