⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memory.txt

📁 汇编编程艺术
💻 TXT
📖 第 1 页 / 共 2 页
字号:
Memory Management Routines
--------------------------

The stdlib memory management routines let you dynamically allocate storage on
the heap.  These routines are somewhat similar to those provided by the "C"
programming language.  However, these routines do not perform garbage
collection, as this would introduce too many restrictions and have a very
adverse effect on speed.

The following paragraph gives a description of how the memory management
routines work.  These routines may be updated in future revisions, however,
so you should never make assumptions about the structure of the memory
management record (described below) or else your code may not work on the
next revision.

The allocation/deallocation routines should be fairly fast.  Malloc and free
use a modified first/next fit algorithm which lets the system quickly find a
memory block of the desired size without undue fragmentation problems (average
case).  The memory manager data structure has an overhead of eight bytes
(meaning each malloc operation requires at least eight more bytes than you ask
for) and a granularity of 16 bytes.  The overhead (eight bytes) per allocated
block may seem rather high, but that is part of the price to pay for faster
malloc and free routines.  All pointers are far pointers and each new item is
allocated on a paragraph boundary.  The current memory manager routines always
allocate (n+8) bytes, rounding up to the next multiple of 16 if the result is
not evenly divisible by sixteen.  The first eight bytes of the structure are
used by the memory management routines, the remaining bytes are available for
use by the caller (malloc, et. al., return a pointer to the first byte beyond
the memory management overhead structure).

NOTE: There was a major change in the way this package works starting with
version 30 of the library.  Prior to version 30, MemInit required a parameter
in the DX register to determine where to allocate the heap and how much
storage to allocate.  Furthermore, the older versions called DOS to deallocate
memory then reallocate it for the heap.  Finally, the older versions required
that you set up a global variable "PSP" containing the program segment
prefix value.

As of version 30, MemInit was split into two routines: MemInit and MemInit2.
MemInit allocates all of available memory (like the standard version of the
earlier MemInit) whereas MemInit2 lets you specify the location and size
of the heap.  The new version calls DOS to get the PSP (so you don't need
to declare the PSP variable just for MemInit).  The new version does not
reallocate memory blocks with DOS calls (which created some problems,
especially with debugger programs).  Finally the new versions work fine
with ".EXE" files which do not get all leftover memory allocated to them.

Most older STDLIB programs will work just fine with the new MemInit routine.
If you relied on MemInit to reallocate memory for you, or if you specified
the location of the heap, you will need to modify your program to use these
new versions of the MemInit routine.


Routine:  MemInit
-----------------

Category:               Memory Management Routine

Registers on Entry:     Nothing
Globals Affected:       zzzzzzseg - segment name of the last segment in your
				    program

Registers on return:    CX - number of paragraphs actually reserved by MemInit


Flags affected:         None

Example of Usage:
						; Don't forget to set up
						; zzzzzzseg before calling
						; MemInit
			MemInit


Description:  This routine initializes the memory manager system.  You must
	      call it before using any routines which call any of the memory
	      manager procedures (since a good number of the stdlib routines
	      call the memory manager, you should get in the habit of always
	      calling this routine.)  The system will "die a horrible death"
	      if you call a memory manager routine (like malloc) without first
	      calling MemInit.

	      This routine expects you to define (and set up) a global
	      names: zzzzzzseg.  "zzzzzzseg" is a dummy segment which
	      must be the name of the very last segment defined in your
	      program.  MemInit uses the name of this segment to determine the
	      address of the last byte in your program.  If you do not
	      declare this segment last, the memory manager will overwrite
	      anything which follows zzzzzzseg.  The "shell.asm" file
	      provides you with a template for your programs which properly
	      defines this segment.

	      On return from MemInit, the CX register contains the number of
	      paragraphs actually allocated.


Include:                stdlib.a or memory.a

Routine:  MemInit2
------------------

Category:               Memory Management Routine

Registers on Entry:     ES-	segment address of the start of the heap.
			CX-	Number of paragraphs to allocate for the heap.

Registers on return:    None
Flags affected:         None

Example of Usage:
			mov	cx, seg HeapSeg
			mov	es, cx
			mov	cx, HeapSize		;In paragraphs!
			MemInit2


Description:  This routine initializes the memory manager system.  You must
	      call it before using any routines which call any of the memory
	      manager procedures (since a good number of the stdlib routines
	      call the memory manager, you should get in the habit of always
	      calling this routine.)  The system will "die a horrible death"
	      if you call a memory manager routine (like malloc) without first
	      calling MemInit2 (or MemInit).

	      This routine lets you decide where the heap lies in memory
	      (as opposed to MemInit which uses all available bytes from
	      the end of your program to the end of memory).

	      Note: you should only call MemInit or MemInit2 once in your
	      program.

Include:                stdlib.a or memory.a

Routine:  Malloc
----------------

Category:              Memory Management Routine

Registers on Entry:    CX - number of bytes to reserve

Registers on return:   CX - number of bytes actually reserved by Malloc
		       ES:DI - ptr to 1st byte of memory allocated by Malloc

Flags affected:        Carry=0 if no error.
		       Carry=1 if insufficient memory.

Example of Usage:
		       mov     cx, 256
		       Malloc
		       jnc     GoodMalloc
		       print   db    "Insufficient memory to continue.",cr,lf,0
		       jmp   Quit
	  GoodMalloc:  mov   es:[di], 0          ;Init string to NULL


Description:  Malloc is the workhorse routine you use to allocate a block of
	      memory.  You give it the number of bytes you need and if it
	      finds a block large enough, it will  allocate the requested
	      amount and return a pointer to that block.

	      Most memory managers require  a small amount of overhead for each
	      block they allocate.  Stdlib's (current) memory manager requires
	      an overhead of eight bytes.  Furthermore, the grainularity is 16
	      bytes.  This means that Malloc always allocates blocks of memory
	      in paragraph multiples.  Therefore, Malloc may actually reserve
	      more storage than you specify. Therefore, the value returned in
	      CX may be somewhat greater than the requested value.  By setting
	      the minimum allocation size to a paragraph, however, the
	      overhead is reduced and the speed of Malloc is improved by a
	      considerable amount.

	      Stdlib's memory management does not do any garbage collection.
	      Doing so would place too many demands on Malloc's users.
	      Therefore, it is quite possible for you to fragment memory with
	      multiple calls to maloc, realloc, and free.  You could wind up in
	      a situation where there is enough free memory to satisfy your
	      request, but there isn't a single contiguous block large enough
	      for the request.  Malloc treats this as an insufficient memory
	      error and returns with the carry flag set.

	      If Malloc cannot allocate a block of the requested size, it
	      returns with the carry flag set.  In this situation, the contents
	      of ES:DI is undefined.  Attempting to dereference this pointer
	      will produce erratic and, perhaps, disasterous results.

Include:              stdlib.a or memory.a


Routine:  Realloc
-----------------

Category:  Memory Management Routine

Registers on Entry:   CX - number of bytes to reserve
		      ES:DI - pointer to block to  reallocate.

Registers on return:  CX - number of bytes actually reserved by Realloc.
		      ES:DI - pointer to first byte of memory allocated by
			      Realloc.

Flags affected:       Carry = 0 if no error.
		      Carry = 1 if insufficient memory.

Example of Usage:
			mov	cx, 1024	;Change block size to 1K
			les	di, CurPtr	;Get address of block into ES:DI
			realloc
			jc	BadRealloc
			mov	word ptr CurPtr, di
			mov	word ptr CurPtr+2, es


Description:  Realloc lets you change the size of an allocated block in the
	      heap.  It allows you to make the block larger or smaller.
	      If you make the  block smaller, Realloc simply frees (returns
	      to the heap) any leftover bytes at the end of the block.  If
	      you make the block larger, Realloc goes out and allocates a
	      block of the requested size, copies the bytes form the old
	      block to the beginning of the new block (leaving the bytes at
	      the end of the new block uninitialized)), and then frees the
	      old block.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -