DOS使用内存控制块来控制和管理内存,这是一个占16字节的结构,位于每个分配得到的内存块的起始地址再向前16个字节这样说可能不是太清楚,过一会再继续说。在DOS下,有两种情况会分配内存,一是使用int 21h的4bh功能加载一个程序,此时DOS会为加载的程序分配两块内存,一块是环境块,用于存放环境串信息,另一块是程序块,用于存放PSP和程序本身;第二种情况是使用int 21h的48h或3ah功能申请或修改内存块;不论用什么方法得到内存块,都会在你得到的内存前面建立一个内存控制块MCB。 我们用int 21h的48h功能调用来说明内存控制块MCB在什么地方,该调用的使用方法如下: 入口:AH=48H BX=要分配的段落数(一个段落为16字节) int 21h 出口:AX=被分配内存的段地址 这个调用完成并成功的话,你得到的内存起始点地址为:AX:0000 那么,MCB在什么位置呐?它在:(AX-1):0000 这个位置正好在你使用的内存块前16字节。 内存控制块的结构如下: 偏移 大小 描述 ---------------------------------------------------- 00h byte 标记,{zh1}一块为5ah,非{zh1}块为4dh 01h word 分配块段址 03h word 分配块段落数 05h 11bytes 保留 要说明的是偏移为01h的分配块段址这个字段,假如我们有个程序A,它的PSP段址为PSP-A,在程序A中申请了一块内存为B,那么B的内存控制块的偏移为1的位置存放的是PSP-A,这个概念很重要,DOS使用PSP的段址作为一个进程的ID,所以实际上这个字段表示的是这块内存的归属,上面这个例子说明内存块B是归属于PSP-A进程的,也就是程序A的,当程序A正常退出时,DOS会沿着MCB链把归属于程序A的所有内存块都释放掉,从这点上也可以看出,如果我们不想让我们程序退出时其中的某块内存也被释放掉,改变一下分配块段址这个字段就可以了。 内存控制块是以链的形式连接在一起的,各控制块指针之间的关系可以用下面的简单公示表达: (控制块指针)i+1 = (控制块指针)i + (分配段落数)i + 1 |