Category : C++ Source Code
Archive   : VCCRT1.ZIP
Filename : HEADCHK.ASM

 
Output of file : HEADCHK.ASM contained in archive : VCCRT1.ZIP
page ,132
title headchk - Validates a heap segment header
;***
;headchk.asm - Validates a heap segment header
;
; Copyright (c) 1988-1992, Microsoft Corporation. All rights reserved.
;
;Purpose:
; Validates the header portion of a heap segment descriptor.
;
;*******************************************************************************

.xlist
include version.inc
include cmacros.inc
include heap.inc
.list

; Validate the assumptions we make about the heap segment descriptor
; and heap list header. All the pointers must be contiguous.

.ERRE start+2 EQ rover
.ERRE rover+2 EQ last
.ERRE last+2 EQ nextseg
.ERRE nextseg+4 EQ prevseg

.ERRE startseg+4 EQ roverseg
.ERRE roverseg+4 EQ lastseg


sBegin code

assumes cs,code

page
;***
; _headchk - Validates a heap segment header
;
;Purpose:
; Inspect the header portion of a heap segment descriptor and
; make sure it's cool.
;
; NOTE: This routine makes some assumptions about the layout
; of the heap descriptor. If that layout is changed, this code
; may break!!!
;
; [NOTE: Careful, _headchk and _listchk use the same exit code.]
;
;Entry:
; ds:bx = heap descriptor
;
;Exit:
; ax = return value as follows:
;
; _HEAPOK - completed okay
; _HEAPEMPTY - near heap not initialized
; _HEAPBADBEGIN - bogus header
; _HEAPBADNODE - malformed node somewhere
;
; ds:bx = same as entry
; cx, dx = same as entry
;
;Uses:
; di, si, es
;Exceptions:
;
;*******************************************************************************

cProc _headchk,,<>

cBegin

push cx ; save caller's cx

; Init some values

cld ; load/search forward
push ds
pop es ; es = heap descriptor segment

; See if the heap is initialized or not.
; [Note: We must check .last to see if heap is init'd, not .start.
; Using _heapadd(), it is possible for .start to be 0 even though the
; the heap is initialized. This is never the case with .last.]

mov ax,[bx].last ; get the end of the heap segment
or ax,ax ; is the segment initialized ??
jz empty ; no, it's empty
;fall thru ; yes, heap segment is initialized

;
; --- Heap is initialized
; (1) validate the checksum value
; (2) make sure last pointer is correct
; (3) make sure rover is in range
; (4) if near heap, make sure prevseg/nextseg are null
;
; es = heap descriptor segment
;

mov ax,ds ; ax = descriptor segment
cmp ax,[bx].checksum ; checksum == descriptor segment ??
jne bad_begin ; nope, error - bad header

mov si,[bx].last ; pointer to last entry
cmp [si],_HEAP_END ; does si point to _HEAP_END ??
jne bad_begin ; no - bad header

mov di,[bx].rover ; di = rover pointer
cmp di,si ; rover > last ??
ja bad_begin ; yes, error
cmp di,[bx].start ; rover < start ??
jb bad_begin ; yes, error

mov ax,[bx].flags ; get heap descriptor flags
and ax,_HEAP_NEAR ; check near heap bit
jz heap_ok ; not near, all done
xor ax,ax ; check for nextseg/prevseg for nulls
lea di,[bx].nextseg ; es:di = address of nextseg pointer
mov cx,4 ; 4 words to check for null
null_check:
scasw ; get another word
jne bad_begin ; jump if not null
loop null_check ; check next word
; fall thru

;
; --- Heap is ok
;

heap_ok:
mov ax,_HEAPOK ; heap is ok
jmp short done ; join common return

;
; --- Heap is empty
; All pointers in the header should be null (start, rover, last,
; prevseg, nextseg).
; ax = 0, es = heap descriptor segment
;

empty:
lea di,[bx].start ; es:di = address of start pointer
mov cx,7 ; 7 words to check for null
next_null:
scasw ; get another word
jne bad_begin ; jump if not null
loop next_null ; check next word
;fall thru

;
; --- Heap is empty
;

heap_empty:
mov ax,_HEAPEMPTY ; heap is empty
jmp short done ; join common return

;
; --- Bad header return
;

bad_begin:
mov ax,_HEAPBADBEGIN ; header is incorrect
;fall thru

;
; --- Common return
; ax = return value
;

done:
pop cx ; restore caller's cx
ret

cEnd


page
;***
; _listchk - Validate a heap list header
;
;Purpose:
; Validate a heap list header. For use with the
; heapwalk/chk/set family of routines.
;
; NOTE: This routine makes some assumptions about the layout
; of the heap descriptor. If that layout is changed, this code
; may break!!!
;
; [NOTE: Careful, _headchk and _listchk use the same exit code.]
;
;Entry:
; ds:bx = address of heap list header
;
;Exit:
; ax = return value as follows:
;
; _HEAPOK - list header is ok
; _HEAPEMPTY - list header is not initialized
; _HEAPBADBEGIN - bogus header
;
;Uses:
; si, dx
;Preserves:
; ds:bx, es:di, cx
;Exceptions:
;
;*******************************************************************************

cProc _listchk,,<>

cBegin

push cx ; save cx (same as _headchk)

;
; Get first heap segment and see if it's 0
;
mov ax,word ptr [bx].startseg+2 ; ax = first segment in heap
or ax,ax ; is it 0 ??
jz nullseg ; yes, segment is null

;
; First segment is not null -- make sure none of the segments are null
;
mov ax,word ptr [bx].roverseg+2 ; ax = rover heap segment
or ax,ax ; seg == null ??
jz bad_begin ; yes, error
mov ax,word ptr [bx].lastseg+2 ; ax = last heap segment
or ax,ax ; seg == null ??
jnz heap_ok ; no, heap is ok
jmp short bad_begin ; yes, error

;
; First segment is null -- make sure all segments and offsets are null
; ax = 0
; ds:bx = heap list descriptor
;

nullseg:
push es ; save caller's registers
push di

mov cx,ds ; es:di = startseg
mov es,cx
lea di,[bx].startseg
mov cx,6 ; 6 words to check for null
cld ; forward
repe scasw ; are all pointers == NULL ?

pop di ; restore registsers
pop es ; (preserve flags)
je heap_empty ; all zero - heap is empty
jmp short bad_begin ; non-zero pointer(s) - bad heap

;
; --- Never get here ---
;

cEnd

sEnd code

end


  3 Responses to “Category : C++ Source Code
Archive   : VCCRT1.ZIP
Filename : HEADCHK.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/