Category : C++ Source Code
Archive   : VCCRT1.ZIP
Filename : BMALLOC.ASM
title bmalloc -- C runtime based heap allocation
;***
;bmalloc.asm - based heap allocation
;
; Copyright (c) 1985-1992, Microsoft Corporation. All rights reserved.
;
;Purpose:
; defines _bfree(), _bmalloc() - allocate/free memory from the
; based heap.
;
;*******************************************************************************
include version.inc
.xlist
include cmacros.inc
include heap.inc
.list
sBegin data
assumes ds,data
externW _bheap ; based heap linked list descriptor
ifndef _NOTCXX_
globalCP _pnhbBasedHeap, 0
endif
sEnd data
externNP _findseg ; find a heap segment
externNP _searchseg ; search a heap segment
externNP _growseg ; grow a heap segment
sBegin code
assumes ds,data
assumes cs,code
page
;***
;void _bfree(bseg, boff) - free block in the based heap
;
;Purpose:
; Free a block of memory in the based heap which was allocated
; by _bmalloc().
;
; [MTHREAD NOTE: Since the freeing of a heap entry is an
; atomic action, the heap lock is not needed. Note that if
; the RESET_ROVER code is implemented, _bfree() must lock/unlock
; the heap.]
;Entry:
; unsigned bseg = based heap segment
; unsigned boff = offset into heap segment
;
; bseg:boff = address of block to be freed
;
;Exit:
;
;Uses:
; ax,bx,cx,dx,es
;
;Exceptions:
;
;*******************************************************************************
cProc _bfree,
parmW bseg ; based heap segment
parmW boff ; offset into based heap segment
cBegin
; Get address and make sure it's not NULL
mov es,[bseg] ; es:si = address
mov si,[boff]
mov cx,es ; is bseg == 0 ??
jcxz _bfend ; yup - just return
mov cx,si ; is boff == 0 ??
jcxz _bfend ; yup - just return
cmp cx,_NULLOFF ; is boff == _NULLOFF ??
je _bfend ; yup - just return
or byte ptr es:[si-2],1 ; free entry
_bfend: ; return
cEnd
page
;***
;_bmalloc(bseg, incr) - allocate a memory block in the based heap
;
;Purpose:
; Allocates a memory block of at least size bytes in the based heap.
; The block will be aligned for the storage of any type of object.
;
;Entry:
; unsigned bseg = based heap segment
; unsigned incr = size of memory block desired
;
;Exit:
; dx:ax = success = address of block (dx = segment, ax = offset)
; = failure = NULL
;
;Uses:
;
;Exceptions:
;
;*******************************************************************************
;--- Single thread version
cProc _bmalloc,
parmW bseg ; unsigned int based heap segment
parmW incr ; unsigned int allocation size
cBegin
ifndef _NOTCXX_
RetryBMalloc:
endif
;
; Make sure the requested size is not too big
;
push ds ; save dgroup
mov dx,[incr] ; cx = request block size
cmp dx,_HEAP_MAXREQ ; cx > maximum legal request size ??
ja error_rtn ; error
;
; Find the appropriate based segment
; dx = size
; ds = dgroup
;
mov bx,dataoffset _bheap ; based heap list header
mov ax,[bseg] ; segment to search for
call _findseg ; get the segment
jc error_rtn ; error, if we didn't find the segment
;
; Try to get a block from the existing segment
; dx = size
; ds:bx = based heap segment descriptor
;
mov cx,dx ; cx = block size
call _searchseg ; try for a block
jnc have_block ; success!!
;
; Try to grow the segment
; cx = size
; ds:bx = based heap segment descriptor
;
call _growseg ; try to grow the block
jc error_rtn ; error, could not grow
call _searchseg ; get the new block
;*** OPTIONAL VALIDITY CHECK
;jc _heap_toast ; *** oops, should always work ***
;***
;
; The block is in hand. Update the roverseg field in the based heap list
; header (analogous to what _fmalloc() does) and exit.
; ds:bx = based heap segment descriptor
; dx:ax = pointer to block (to be returned to the caller)
;
have_block:
mov si,ds ; stash selector in si
pop ds ; restore dgroup
mov di,dataoffset _bheap ; ds:di = based heap list header
mov word ptr [di].roverseg,bx ; update rover seg
mov word ptr [di].roverseg + 2,si
jmp short bdone ; return the result
;
; Error return. We will always get here if _bmalloc() is going to
; return _NULLOFF.
;
error_rtn:
pop ds ; restore dgroup
ifndef _NOTCXX_
if sizeC
mov cx, word ptr (_pnhbBasedHeap+2)
or cx, word ptr (_pnhbBasedHeap)
jz rtn_NULLOFF
else ;not sizeC
cmp (_pnhbBasedHeap), 0
je rtn_NULLOFF
endif ;not sizeC
push [bseg]
push [incr]
call (_pnhbBasedHeap)
add sp, 4
or ax, ax
jnz RetryBMalloc
rtn_NULLOFF:
endif ;not _NOTCXX_
mov ax,_NULLOFF ; Set dx:ax = bseg:_NULLOFF
mov dx,[bseg] ; Fall through to bdone.
;
; Common exit
; (dx:ax = return value)
;
bdone:
cEnd
sEnd code
end
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
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/