Win32汇编--Windows 的内存安排--------2015年9月28日 00:01:54

这节课我们需要理解三个概念:

每个应用程序都有自己的4 GB的寻址空间,就算这个程序只暂 1KB的内存;

不同应用程序的线性地址空间是隔离的,尽管他们在内存中是搞在一起;

时刻要记住,DLL程序是“小三”,因此它们没有自己“私有”的空间。

本节课我们将图文并茂地来进行原理层面的分析!

虚拟内存安排:
Windows 系统一般在硬盘上建立大小为物理内存两倍左右的交换文件用作虚拟内存。
利用 80386处理器的内存分页机制,交换文件的寻址上可以很方便地作为物理内存使用。(只需要在真正调用的时候将其读入物理内存并同时修改线性地址映射到这块内存即可)。
同样道理,反正是映射一个地址而已,所以被执行的程序也可以不必装入内存,只需要在页表中建立映射关系,真正运行到这段代码才调入内存。

众所周知,Windows 是一个分时的多任务操作系统,CPU时间(就是CPU运行的过程)被分成一个个的时间片后分配给不同程序轮流使用。
在A程序的时间片中,和这个程序执行无关的部分(B和C等其他程序的代码和数据)并不需要映射到线性地址中。
附加解析:
内存中,所有的程序都搞在一起,关系十分混乱;
CPU只能看到线性地址(假的),每个程序拥有自己的线性地址(小三除外)。

总结:WIN32编程中几个很重要的概念
第一点:
每个应用程序都有自己的4 GB的寻址空间。
该空间可存放操作系统、系统DLL和用户DLL的代码,它们之中有各种函数供应用程序调用。
再除去其他的一些空间,余下的是应用程序的代码、数据和可以分配的地址空间。

第二点:
不同应用程序的线性地址空间是隔离的。
虽然它们在物理内存中同时存在,但在某个程序所属的时间片中,其他应用程序的代码和数据没有被映射到可寻址的线性地址中,所以是不可访问的。
从编程的角度看,程序可以使用4 GB的寻址空间,而且这个空间是“私有”的。

第三点:
DLL程序没有自己“私有”的空间。
它们总是被映射到其他应用程序的地址空间中,当做其他应用程序的一部分运行。
原因很简单,如果它不和其他程序同属一个地址空间,应用程序该如何调用它呢?


从 WIN32汇编的角度看内存寻址
如果坚持不到这句话出现的同学就因为前边Windows原理太复杂而放弃的童鞋,小甲鱼觉得很可惜……

Win32汇编中的内存访问远比DOS下的分段寻址方式简单,这是为什么呢?
因为Windows是一个多任务的操作系统,最首要的宗旨就是“稳定压倒一切”。如果把描述符表以及页表等内容交给用户程序管理是很不安全的。

任何权限上开放引发的安全问题都是很严重的,如Windows 9x中的中断描述符表是可写的,CIH病毒可利用它将自己的权限提高到优先级0;

而Windows NT下的中断描述符表是不可写的,CIH病毒在Windows NT下就无法使用同样的方法进驻内存。

关于CIH病毒可以到鱼C论坛“资源分享”版块下载_
正因为如此,Windows操作系统干脆为用户程序“安排好了一切”。
具体表现在为用户程序的代码段、数据段和堆栈段全部预定义好了段描述符。这些段的起始地址为0,限长为ffffffff,所以用它们可以直接寻址全部的4 GB地址空间。
程序开始执行的时候,CS,DS,ES和SS都已经指向了正确的描述符,在整个程序的生命周期内,程序员不必改动这些段寄存器,也不必关心它们的值究竟是多少(实际上是想改也改不了)。

所以对Win32汇编程序来说,整个源程序中竟然可以不用出现段寄存器的身影。
这在DOS汇编编程中是不可想像的。

回顾之前提出的问题:
“为什么在WIN32汇编源代码中看不到CS,DS,ES,SS等段寄存器的使用?”

答案是:并不是Win32汇编源代码用不到段寄存器,而是用户在使用中不必去关心段寄存器!

posted on 2015-08-16 21:44  木屐  阅读(397)  评论(0编辑  收藏  举报

导航