4.0内存
这部分将解释在Windows中内存是如何管理的。
3. 1Dos和win3.xx
在像用于Dos和Win3.xx的16位程序中,内存被分成许多个段。这些段的大小为64kb。为了存储内存,需要一个段指针和一个偏移址指针。段指针标明要使用哪个段,offset指针标明在段本身的位置。看下图:
内存
段 1
(64kb)
段 2
(64kb)
段 3
(64kb)
段 4
(64kb)
更多
注意下面关于16位程序的解释,后面有更多关于32位的(但不要跳过这部分,要理解32位的内存管理,这部分很重要)上表是全部的那内存,被划分成了64kb的多个段。最多有65536个段。现在取出一段:
段 1(64kb)
Offset 1
Offset 2
Offset 3
Offset 4
Offset 5
更多
为了指向段中的位置,需要使用offset。一个offset是段中内部的一个位置。每个段最多有65536个offset。内存中地址的记法是:
SEGMENT:OFFSET
例如:
0030:4012(均为16进制)
它的意思是:段30,offset4012。为了查看那个地址中有什么。你先要到段30,然后到该段的offset4012。在前一章中,你已经学过了段和指针寄存器。例如,段寄存器有:
CS
代码段
DS
数据段
SS
栈段
ES
扩展段
FS (only 286+)
全功能段
GS (only 386+)
全功能段
顾名思义:代码段(CS)包括了当前的代码执行到了哪部分。数据段是用来标明哪段中取出数据。栈指栈段(后面有更多)。ES,FS, GS是全功能的寄存器,并且可以用于任何段(虽然在Windows中不行)。
指针寄存器大多数时装有offset,但全功能寄存器(ax, bx, cx, dx等)也可以这么用。Ip标明当前指令执行到了哪个offset。Sp保存了当前栈的offset1,在ss(栈段中)。
4.2 32位Windows
你可能已经注意到了关于段的一切是乏味的。在16位编程中,段是必不可少的。幸运的是,这个问题已经在32位Windows(95及以上)中得到解决。你仍然有段,但不用管他们了因为它们不再是64kb,而是4GB。你如果尝试着改变段寄存器中的一个,windows甚至会崩溃。这称为平坦(flat)内存模式。只有offset而且是32位的,因而范围从0到4,294,967,295。内存中的每一个地址都是用offset表示的。这真是32位胜于16位的最大优点。所以,你现在可以忘了段寄存器并把精神集中在其他的寄存器上。