大神们,小弟我就想知道从程序虚拟地址到物理地址的过程如何就这么难啊

大神们,我就想知道从程序虚拟地址到物理地址的过程怎么就这么难啊?
大神们,小弟我就想知道从程序虚拟地址到物理地址的过程如何就这么难啊
帮帮我吧,百度大神不给力啊,没有讲的清楚,我承认我是外行,但是我心是真诚的啊,特到此地求助,我不需要很复杂的讲解,就用举例 加 简单的白话给我讲明白道理就行,你太专业我也听不懂啊 一样白瞎啊。

首先我说下 我大概知道的情况 和 我想知道集我不太明白的地方!

我知道的情况有这些  程序的代码在编译器没翻译之前 里面都是变量名 然后经过编译器翻译之后 把变量名都变成了偏移地址 也就是逻辑地址。

然后经过操作系统再负责把 逻辑地址+段基址 变成线性地址。

然后分页机制的保护模式 再把线性地址 变成 物理地址 最终的地址!!

而且听说每个进程都是独立的,都有4GB虚拟空间地址!

上面这些就是我查资料,到目前位置所知道的所有内容了。
-----------------------------------------------------
下面是我有的地方不太明白的搞不懂的:

1请用数字 加法 等举例的方式 给我演示一遍 从程序代码到物理代码的具体算法过程?
比如 变量名a 经过编译器后 把a变成一个偏移地址 00001
然后加基地址00001 变成00002 是线性地址,因为我不知道什么是基地址 所以麻烦你们举例的时候 尽力用简单的数举个例子。在然后有了线性地址了吧 ,怎么怎么的经过页目录表 就得到物理地址了。


2请问页目录表的结果,能简单说下吗,我自己查了下,可惜也没看的太明白?
我理解的是这样目录表有1024目录
然后每个目录里又有1024页
然后每个页里又有1024页项
然后每项目是4字节
最后这样算下来就是4GB虚拟地址?就是每个进程的4GB就是这么得来的吗?

那我就有疑问了,每个进程的目录表都有1024个目录,那怎么区分啊?那是不是在目录前还应该有个东东区分啊?比如还应该有个大目录表0-1023这样的,这样A进程给它分配到0页,B进程分配到1页去?
如果是这样的话 那应该就是 有4个1024吧 ?但是第一个的1024才算是页的标志?后面的3个1024是每个进程都相同的,所以才说都有独立的4GB虚拟地址,等于除了开头的页不一样,剩下里面的都一样 对吗?



3那是不是说所有程序的代码里面的虚拟地址都一样,然后转换后的线性地址也都一样?但是分页不同,所以对应的物理地址就不同?

那还有个情况 假设比如A进程500M  B进程占500M 物理内存是1G
因为用到虚拟内存了 那真实内存空间就是 物理内存+虚拟内存(假设虚拟内存4G)=5G

现在是A进程先来的 得到第一页 占了物理内存500M

这时候B进程又进来了 得到第二页 也占了物理内存500M

那我想问 B进程 进来的时候 是占剩余空闲的部分500M,还是把A进程转移到虚拟内存上去,把空间全给B进程使用呢?

因为我听说分页时候 是跟物理内存的块 一块 两块 什么的想对应的 说进程之间切换都是按页切换的?什么意思 没搞懂这个概念 是不是说把A进程整页的移出去,放B进程整页进来?

后来我又突然想到一个问题,既然每个进程都是独立4GB虚拟地址,那物理内存实际没那么大 假设物理内存4GB,假设A和B进程都是4GB全满的状况下,那如果B进程进来 肯定是整页把A进程请出去,那如果像上面说的 实际进程也不会都是全满4GB的,那如果2进程加起来虚拟地址都没超过物理内存总和 ,那是不是说就不用整页的把A进程请出去了?可以A和B共存在物理内存里?

还一个问题 就是每个进程都是独立4GB的 那可是物理内存没那么大 那怎么保证每页和物理地址一一对应,难道不足的地方用虚拟内存补上?那如果A进程占4GB B进程占4GB 物理内存1GB 是不是说要开辟硬盘虚拟内存7个GB才行啊?如果这时候在进来一个C程序占4GB,是不是系统就完蛋了 因为虚拟内存和物理内存都装不下了 超过范围了就崩溃了吧???

纠正下 我突然琢磨了一下 好像页目录那里 我理解有错误 应该是有多少页目录表就有多少物理内存块 一一对应

也就是说4GB物理内存只有一个,但是每个进程都可以有4GB虚拟地址,我突然明白了,就是页目录表总大小也是4GB,这样和物理内存就对上号了,页目录表有1024页 然后物理内存也有1024块 一一对应,每页是4M大小,然后物理块也是每块4M大小 ,这样不就OK啦,那假如A进程是40M,那得到应该就不是一页了 ,应该是1-10页全包了,因为每页4M,10页才是40M,这样剩下的物理内存还有空闲页可以留着给其它进程使用?

也不知道我说的对不对,一片迷茫啊-。-

呼呼 累死我了 打了这么多 也不知道你们看的懂看不懂 呜呜~~

不求别的 只求我心中这些疑问能有个满意的答复啊 我问的这些都有些偏底层了 我想着要是汇编大神们都没人知道的话,那估计放眼整个论坛也不会有人知道了…………

真心求教啊 希望有好心人 耐心的帮我抛开云雾见月明 柳暗花明又一村啊 拜托了!底层们的神啊 兄弟这先谢谢了!别让我失望啊  都说码代码不易 我码字也是人工的。。。。









------解决方案--------------------
以线性地地0x12345678为例,
其二进制为0001001000    1101000101    011001111000,如上面所示,它实际上分了三段,
第一段10位是页目录,表示页表项在页目录中的偏移。其基址在cr3中。
第二段10位是页表,表示4K的物理页在页表的中的偏移。
第三段12位是页内偏移。

寻址时,由10位的页目录(第一段)和cr3定位到一个页表,在此页表中由10位页
表偏移(第二段)定位到一个物理页,在这个物理页中由12位页内偏移(第三段)定
位到一字节。

cr3中存储的是页目录的基址(是物理地址)。
页目录中存储的是页表的基址(是物理地址)。
页表中存储的是物理页的基址(是物理地址)。

任务可以有自己的页目录,页表,当任务切换时,把页目录的物理地址装入cr3,
这样每个进程里的线性地址0x12345678实际映射的物理页都可以是不同的,也可