win32 007
这是不是说,在保护模式下,段寄存器就不再有用了呢?
答案是否定的!实际上段寄存器更有用了,虽然在寻址上不再有分段的限制问题,但在保护模式下,一个地址空间是否可以被写入,可以被多少优先级的代码写入,是不是允许执行等涉及保护的问题就出来了。
要解决这些问题,必须对一个地址空间定义一些安全上的属性。段寄存器这时就派上了用途,不妨将这些属性存放在段寄存器中!
但是问题来了,涉及属性和保护模式下段的其他参数,要表示的信息太多了,要用64位长的数据才能表示。我们把这64位的属性数据叫做段描述符(Segment Descriptor)。
80386的段寄存器仍然是16位的,无法放下保护模式下64位的段描述符。如何解决这个新的问题呢?
解决办法是把所有段的段描述符顺序放在内存中的指定位置,组成一个段描述符表(Descriptor Table)
而段寄存器中的16位用来做索引信息,指定这个段的属性用段描述符表中的第几个描述符来表示。
这时,段寄存器中的信息不再是段地址了,而是段选择器(Segment Selector)。可以通过它在段描述符表中“选择”一个项目以得到段的全部信息。
既然这样,段描述符表放在哪里呢?
80386中引入了两个新的寄存器来管理段描述符表。一个是48位的全局描述符表寄存器GDTR,一个是16位的局部描述符表寄存器LDTR。
那么,为什么有两个描述符表寄存器呢?
GDTR指向的描述符表为全局描述符表GDT(Global Descriptor Table)。
它包含系统中所有任务都可用的段描述符,通常包含描述操作系统所使用的代码段、数据段和堆栈段的描述符及各任务的LDT段等;全局描述符表只有一个。
LDTR则指向局部描述符表LDT(Local Descriptor Table)。
80386处理器设计成每个任务都有一个独立的LDT。
它包含有每个任务私有的代码段、数据段和堆栈段的描述符,也包含该任务所使用的一些门描述符,如任务门和调用门描述符等。
不同任务的局部描述符表分别组成不同的内存段,描述这些内存段的描述符当做系统描述符放在全局描述符表中。
和GDTR直接指向内存地址不同,LDTR和CS,DS等段选择器一样只存放索引值,指向局部描述符表内存段对应的描述符在全局描述符表中的位置。
随着任务的切换,只要改变LDTR的值,系统当前的局部描述符表LDT也随之切换,这样便于各任务之间数据的隔离。但GDT并不随着任务的切换而切换。
看到这里,读者可能会提出一个问题,既然有全局描述符表和局部描述符表两个表,那么段选择器中的索引值对应哪个表中的描述符呢?
实际上,16位的段选择器中只有高13位表示索引值。
剩下的3个数据位中,第0,1位表示程序的当前优先级RPL;第2位TI位用来表示在段描述符的位置;TI=0表示在GDT中,TI=1表示在LDT中。
图说寻址路线:
在保护模式下,同样以xxxx:yyyyyyyy格式表示一个虚拟地址。
注意,xxxx(16位,相当于8086时代的段地址) 保存在段寄存器,yyyyyyyy(32位,相当于8086时代的偏移地址)保存在通用寄存器。
下边,小甲鱼从图片来给大家做演示!
图说寻址路线
Win32基础知识4
让编程改变世界
Change the world by program
80386的内存分页机制
在实模式下寻址的时候,“段寄存器+偏移地址”经过转换计算以后得到的地址是“物理地址”,也就是在物理内存中的实际地址。
而保护模式下,“段选择器+偏移地址”转换后的地址被称为“线性地址”而不是“物理地址”。那么,线性地址就是物理地址吗?
答案可能是“是”,也可能是“不是”,这取决于80386的内存分页机制是否被使用。
为什么会有内存分页机制?!
我们来回顾一下:在单任务的DOS系统中,一个应用程序可以使用所有的空闲内存。
程序退出后,操作系统回收所有的碎片内存并且合并成一个大块内存继续供下一个程序使用。
内存合并过程中的一个极端情况是当系统中有多个TSR程序时,早装入内存的TSR被卸载后,后装入的TSR会留在内存的中间部位,把空闲内存隔成两个区域。
这时应用程序使用的最大内存块只能是这两块内存中较大的一块,无法将它们合并使用。
对于一个多任务的操作系统,内存的碎片化是不能容忍的。否则,经过一段时间后,即使空闲内存的总和很大,也可能出现任何一片内存都小到无法装入执行程序的地步。
所以多任务操作系统中碎片内存的合并是个很重要的问题。
80386处理器的分页机制可以很好地解决这个问题。
80386处理器把4 KB大小的一块内存当做一“页”内存,每页物理内存可以根据“页目录”和“页表”,随意映射到不同的线性地址上。
这样,就可以将物理地址不连续的内存的映射连到一起,在线性地址上视为连续。
在80386处理器中,除了和CR3寄存器(指定当前页目录的地址)相关的指令使用的是物理地址外,其他所有指令都是用线性地址寻址的。
名词扫盲:
CR3 用于保存页目录表页面的物理地址,因此被称为PDBR。
由于目录是页对齐的,所以仅高20位有效,低12 位保留供更加高级的处理器使用。
向CR3中装入一个新值时,低12位必须为0,从 CR3中取值时,低12位被忽略。
还有,是否启用内存分页机制是由80386处理器新增的CR0寄存器中的位31(PG位)决定的。
如果PG=0,则分页机制不启用,这时所有指令寻址的地址(线性地址)就是系统中实际的物理地址;
当PG=1的时候,80386处理器进入内存分页管理模式,所有的线性地址要经过页表的映射才得到最后的物理地址。废话不多说,先上美图!!
一个xxxx:yyyyyyyy格式的虚拟地址,经过上节课所示的段地址转换步骤后得到32位的线性地址zzzzzzzz(步骤①)。
当禁用分页机制时,线性地址就是物理地址,处理器直接从物理内存存取数据(步骤②);
当启用分页机制时,得到线性地址的方法还是一样(步骤1′),但是还要根据页目录和页表指定的映射关系把地址映射到物理内存的真正位置上(步骤3′)。
然后,CPU以映射后的物理地址在物理内存中存取数据。这个过程对于指令来说是透明的。
内存分页管理只能在保护模式下才可以实现,实模式不支持分页机制。
但不管在哪种模式下,所有寻址指令使用的都是线性地址,程序不用关心数据最后究竟存放在物理内存的哪个地方。
页表规定的不仅是地址的映射,同时还规定了页的访问属性,如是否可写、可读和可执行等。
比如把代码所在的内存页设置为可读与可执行,那么权限不够的代码向它写数据就会引发保护异常。利用这个机制可以在硬件层次上支持虚拟内存的实现。
页表可以指定一个页面并不真正映射到物理内存中。这样,访问这个页的指令会引发页异常错误。这时,处理器会自动转移到页异常处理程序中去。
操作系统可以在异常处理程序中将硬盘上的虚拟内存读到内存中并修改页表重新映射,然后重新执行引发异常的指令。
这样指令可以正常执行下去。请看图!
win32 007相关推荐
- 瑞星:“007小游戏论坛”、“2144小游戏”等网站被挂马
据瑞星"云安全"系统统计,2月9日,共有482,068人次的网民遭到网页挂马攻击,瑞星共截获了136,597个挂马网址.近期"后门"程序异常猖獗,瑞星公司提醒广 ...
- Don’t Use the Win32 API PostThreadMessage() to Post Messages to UI Threads(翻译)
大龙的博客 C++博客 | 首页 | 发新随笔 | 发新文章 | 联系 | 聚合 | 管理 Don't Use the Win32 API PostThreadMessage() to Post Me ...
- C#中使用Win32和其他库
C# 用户经常提出两个问题:"我为什么要另外编写代码来使用内置于 Windows 中的功能?在框架中为什么没有相应的内容可以为我完成这一任务?"当框架小组构建他们的 .NET 部分 ...
- 在 C# 中通过 P/Invoke 调用Win32 DLL
,.NET Framework 1.0 或 1.1 版类库中存在任何 Windows 所没有的功能限制都不足为怪.毕竟,32 位的 Windows(不管何种版本)是一个成熟的操作系统,为广大客户服务了 ...
- Win32 环境下的堆栈
原文已经找不到,作者应该是:http://blog.csdn.net/slimak 但是没有找到此文,其中丢了2幅图 简介 在Win32环境下利用调试器调试应用程序的时候经常要和堆栈(Stack) ...
- Win32.Lioten.SG病毒
病毒名称:Win32.Lioten.SG 疯狂性:低 破坏性:中 普及度:中 Win32.Lioten.SG病毒描述: Win32.Lioten.SG是一种通过网络共享传播的蠕虫,还会利用Window ...
- win32的一个售票程序,收获有非常的多
先秀一下我的收获吧! 1.在创建非模态对话框的时,需要用到createdialog函数,第二个参数需要注意是填写对话框的资源标识符(id),之后需要调用showwindow来显示对话框:或者不这么做也 ...
- “996 是福利,007 才是常态”?!千万程序员怒怼每日优鲜!
呔!热度不是你想蹭,想蹭就能蹭-- 作者 | 仲培艺 封图 | CSDN 付费下载自东方IC 出品 | 程序人生(ID:coder_life) App Store 评分一日之间从 4.5 断崖直降至 ...
- 机器人替代研究员,工作007,完成688次实验,登上Nature封面
点击上方"视学算法",选择"星标" 快速获得最新干货 本文转自机器之心 今天也要做实验吗?不必了,现在有机器人可以帮忙. 在化学.生物等领域,不少研究生的生活可 ...
最新文章
- 设计模式 - Mediator
- 浪潮服务器5112面板灯_SA5112M4 – IPMI设置
- ThinkPHP6内核学生成绩管理系统源码
- AD画最小系统笔记(一)
- 详解DFT的scan(边界扫描)
- 以太坊之dapp例子
- uni-app在手机上背景图片不显示
- HDOJ 5234 Happy birthday
- 控制电缆分布电容产生的原因及电容量计算
- matlab中 %d,%f,%c,%s代表的输出格式
- 一起来探索从双击程序到开始运行期间计算机经历了哪些过程
- table中填写数据并批量增加
- 计算机应用考试怎么改卷的,电脑阅卷流程是这样的!读完可多拿20分(转给考生,这对他们有用)...
- weblogic(10.3.6)
- 编写一个C 程序,并使用系统调用fork()创建一个子进程
- 缓存模式【缓存使用几种模式】【刘新宇】
- HDU6203 ping ping ping 【LCA+BIT】
- Linux驱动——驱动分离思想和总线设备驱动模型
- 残差神经网络—代码详解
- k8s --洗洗脑--云计算趋势
热门文章
- STM32——RTC实时时钟原理+BKP寄存器原理
- 'net' 不是内部或外部命令,也不是可运行的程序 或批处理文件。'net' 不是内部或外部命令,也不是可运行的程序 或批处理文件。
- 分享一个简单的迭代学习机器人双臂控制(MATLAB)
- java二嗨租车项目_Java入门第二季第六章项目实战(租车系统)
- 一起动才够嗨!Android CoordinatorLayout 自定义 Behavior
- 循环队列的应用——舞伴配对问题:在舞会上,男、女各自排成一队。舞会开始时,依次从男队和女队的队头各出一人配成舞伴。如果两队初始人数不等,则较长的那一队中未配对者等待下一轮舞曲。假设初始男、女人数及性别
- 开发工具 - WakaTime 时间记录
- 快递员上门取件api接口技术对接java文档
- ip中继对接_无线路由中继以及本地固定IP设定
- 大学我这样过,成了别人眼中的大神