这个说来话长了. 8086体系的CPU一开始是20根地址线, 寻址寄存器是16位, 16位的寄存器可以访问64K的地址空间, 如果程序要想访问大于64K的内存, 就要把内存分段, 每段64K, 用段地址+偏移量的方法来访问.
后来386CPU出来之后, 采用了32条地址线, 地址寄存器也扩为32位, 这样就可以不用分段了, 直接用一个地址寄存器来线性访问4G的内存了. 这就叫平面模式.
为了和16位的软件保持兼容, 386的线性内存访问功能只在一种叫"保护模式"的状态上使用, 在这种状态下, 一切程序都可以用线性地址(不分段)访问自己所拥有的4G的内存空间, 但是不能访问其他程序的空间. 如果有程序要访问不该访问的内存(一般只有病毒才会这么作), 就会出系统错误, CPU就用中断通知OS, 这样的进程会被OS发现, 并杀死, 不会影响其他程序. 在windows里常见的系统错误"某某内存不能读写"就是这种问题, 这都不是windows的问题, 而是一些破程序的问题.
在这种情况下, 实际是CPU和OS一起保护了程序的内存, 因此叫做保护模式.
实际上当时内存是不可能有4个G的, 而且是每个程序都要有4G的空间. 为了为每个程序都提供4G内存, 386及以后的CPU采用"页"的方式来管理内存, 把内存分为一个个的页, 页的物理地址与每个程序虚拟的4G线性地址用一个表格保存.
程序用线性地址访问内存. 如果这个内存还没有用过, 就找一个内存页来假装涉及的线性内存段. 如果这个内存长期不用, 操作系统就把内存页存到硬盘上去, 就叫虚存交换文件. 如果这个内存所在的页已经分配过, 但是没有在实存里, 那么CPU就出现一个缺页中断, 由操作系统把硬盘交换文件里的页内数据读出来, 在实存中找一块写进去, 修改页地址和线性地址的对应表格, 然后请程序继续运行.
386可以假装自己是一个16位的CPU, 用16位的分段方式工作, 和保护模式相对的, 这种模式就叫做实模式. |