这几天看windows内存管理看的头都大了,什么分段,什么分页。。。还好他们的机制我都大致看懂了,不过现在有几个问题想问一下各位高手们:
1,书上说分页是可选的,那是不是说在保护模式下可以不用分页?
2,反汇编后形成的地址都是诸如YYYYYYYY的虚拟地址,而罗云彬老师在他的《WIN32汇编教程》开头讲的虚拟地址是如XXXX:YYYYYYYY的形式。我知道XXXX是指段地址,在保护模式下是段选择值。我想问一下,这个段地址是怎么得来的?一个段地址又是怎么确定的,由谁管理呢?
3,GDT和LDT中的值是怎么形成的呢?
4,JIURL的《玩玩Win2k内存篇》里面说到页目录和页表都必须映射到虚拟地址空间中。既然虚拟地址在转换为物理地址时,页目录的基地址是确定的,存在CR3寄存器中,而页目录项中存的又是页表的物理地址,也能确定,那么实际上只要在内存中存放了页目录和页表,由操作系统管理就行了,为什么却要映射到虚拟地址上去?
5,操作系统切换线程,只要在TSS中读取相关数据就行了吧?
我查了不少资料,这些问题始终没搞明白,在此希望能有哪位好心人不吝赐教,本人将100分感谢~~
------解决方案--------------------------------------------------------
1,书上说分页是可选的,那是不是说在保护模式下可以不用分页?
完全可以不用分页,但那要做会降低内存管理的效率和便捷。
2,反汇编后形成的地址都是诸如YYYYYYYY的虚拟地址,而罗云彬老师在他的《WIN32汇编教程》开头讲的虚拟地址是如XXXX:YYYYYYYY的形式。我知道XXXX是指段地址,在保护模式下是段选择值。我想问一下,这个段地址是怎么得来的?一个段地址又是怎么确定的,由谁管理呢?
这个是有gdt或ldt中的描述符确定的,你用ollydbg调试一下可以看到段寄存器中的内容,
在配合masm kernel sdk 中的gdt查看工具可以看到段基址、界限、类型等内容。
3,GDT和LDT中的值是怎么形成的呢?
os填入的。
4,JIURL的《玩玩Win2k内存篇》里面说到页目录和页表都必须映射到虚拟地址空间中。既然虚拟地址在转换为物理地址时,页目录的基地址是确定的,存在CR3寄存器中,而页目录项中存的又是页表的物理地址,也能确定,那么实际上只要在内存中存放了页目录和页表,由操作系统管理就行了,为什么却要映射到虚拟地址上去?
可以不映射到虚拟地址,但windows映射了。
5,操作系统切换线程,只要在TSS中读取相关数据就行了吧?
还要靠cpu的支持和os自身的其他支持。
------解决方案--------------------------------------------------------
4.
可以不映射的
但是,如果不映射的话,你如何动态修改页表?代码访问的地址都是虚拟地址。
所以:
如果你只是在学习保护模式时写代码练习练习,可以先在实模式下把页表建立好,进保护模式后不需要再管页表,自然不需要映射。
如果是写实际的操作系统内核,那需要动态修改页表,就必须映射。
------解决方案--------------------------------------------------------
1.补充一下,Windows号称是“段页式”内存管理,但分页机制是被用来设计支持虚拟内存,主要是因为有时用户需要运行内存占用量超过物理内存的应用程序,当不考虑支持虚拟内存时,分页机制便可有可无。
2.保护模式下段地址实际上是某种形式的指针,所指内容由全局/局部符号描述表确定,实际上CPU启动时为实模式,在操作系统构建完GDT,LDT等准备工作后通过改写特征值进入保护模式。