linux 内核源代码情景分析——Intel X86 CPU 系列的寻址方式
当我们说一个CPU是“16位”或“32”位时,指的是处理器中“算数逻辑单元”(ALU)的宽度。数据总线通常与ALU具有相同的宽度。当Intel决定在16位CPU 8086中采用1M字节的内存空间,地址总线的宽度也就确定了,那就是20位。问题就来了:既然是ALU是16位,也就是说直接加以运算的指针长度是16位,即这个指针所能代表的地址最多有216,不能达到20位地址总线所能寻址的最大空间,于是Intel在8086 CPU中设置了4个“段寄存器”:CS、DS、SS和ES,分别用于可执行代码、数据、堆栈和其他。每个段寄存器都是16位的,对应于地址总线中的高16位。每条“访内”指令中的“内部地址”都是16位的,但是在送上地址总线之前都在CPU内部自动的与某个段寄存器的内容相加,形成一个20的实际地址。这样,就实现了从16位内部地址到20位实际地址的转换。转换公式:实际地址 = 段寄存器 + (内部地址<<4)。
由于8086这种到内存寻址方式缺乏对内存空间的保护,所以为了区别于后来的“保护模式”,就称为“实地址模式”。针对8086这种缺陷,Intel从80286开始实现“保护模式”,不久后80386 CPU也开发成功了,从80386以后,虽然在速度和功能上不断的提改进,但并无重大的质的改变,遂统称为i386结构,下面我们将以80386为背景,介绍i386的保护模式。
1、虚拟地址、逻辑地址、线性地址、物理地址的区别

由图可以看出它们之间的区别
2、分段机制

分段步骤:
1)先检查段选择符TI,确定段描述符保存在GDTR还是LDTR中
2)从段选择符高13位(见下图的段选择符格式)* 8 + GDTR中的内容得到段基地址。也可以这样想,GDTR存放的是段描述符表这个数组的首地址,而段选择符的高13位*8是其下标,因为段描述符是8字节长,所以在段描述表里是以8字节为一个单位
3)然后将2)得到的值与偏移量相加就得到了线性地址
3、段选择符格式

GDT的第一项是”空选择符“(即索引值为0,TI标志为0),当把它加载到一个段寄存器(除了CS和SS之外)中时,处理器不会产生异常,但是当使用含有空选择符的段寄存器访问内存时就会产生异常。段选择符的值通常由链接编辑器或链接加载程序进行设置或修改,而非应用程序.
为了减少地址转换时间和复杂性,处理器提供了6个段寄存器,为了访问某个段的程序,必须把段选择符加载到一个段寄存器中,为了避免每次访问内存时都去读、解码一个段描述符和引用段描述符表,每个段寄存器都有一个“可见”部分和“隐藏”部分(影子寄存器),当一个段选择符被加载到一个段寄存器可见部分中时,处理器也同时把段选择符指向的段描述符中的段地址、段限长和访问控制信息加载到段寄存器的隐藏部分中。缓冲在段寄存器(可见和隐藏部分)中的信息时的处理器可以在进行地址转换时不再需要花费时间从段描述符中读取基地址和段限长。操作系统必须保证对描述符表的改动反映到影子寄存器中,最简单的方法是在对描述符表中描述符作过任何改动之后就立刻重新加载6个段寄存器
4、段描述符格式

B31——B24、B23——B16、B15——B0组合成段基地址Base,Base为32位
L19——L16、L15——L0组合成段限长Limit,Limit为20位
G颗粒度,G=0,Limit单位是字节,G=1,Limit单位是4KB
D 如果段偏移量是32位置1,若是16位,清0
AVL 系统软件可用位,忽略
P为0表示不在内存中,linux总是为1
DPL 表示为访问这个段而要求的CPU最小的优先级
S系统标志:0表示是一个系统段,否则是普通的代码段或数据段
type 指定段的类型、说明段的访问种类以及段的扩展方向
linux 内核源代码情景分析——Intel X86 CPU 系列的寻址方式的更多相关文章
- Linux内核源代码情景分析系列
http://blog.sina.com.cn/s/blog_6b94d5680101vfqv.html Linux内核源代码情景分析---第五章 文件系统 5.1 概述 构成一个操作系统最重要的就 ...
- Intel X86 CPU 系列的寻址方式
Intel X86 CPU 系列的寻址方式 数据总线和地址总线要尽量相同,这个是一个地址就是一个指针.
- linux 内核源代码情景分析——地址映射的全过程
linux 内核采用页式存储管理.虚拟地址空间划分成固定大小的"页面",由MMU在运行时将虚拟地址映射成某个物理内存页面中的地址.页式内存管理比段式内存管理有很多好处,但是由于In ...
- Linux内核源代码情景分析-fork()
父进程fork子进程: child = fork() fork经过系统调用.来到了sys_fork.具体过程请參考Linux内核源码情景分析-系统调用. asmlinkage int sys_fork ...
- linux 内核源代码情景分析——linux 内存管理的基本框架
386 CPU中的页式存管的基本思路是:通过页面目录和页面表分两个层次实现从线性地址到物理地址的映射.这种映射模式在大多数情况下可以节省页面表所占用的空间.因为大多数进程不会用到整个虚存空间,在虚存空 ...
- linux 内核源代码情景分析——linux 内核源代码中的C语言代码
linux 内核的主体是以GNU的C语言编写的,GNU为此提供了编译工具gcc.GNU对C语言本身作了不少扩充. 1) gcc 从 C++ 语言中吸收了"inline"和" ...
- linux 内核源代码情景分析——用户堆栈的扩展
上一节中,我们浏览了一次因越界访问而造成映射失败从而引起进程流产的过程,不过有时候,越界访问时正常的.现在我们就来看看当用户堆栈过小,但是因越界访问而"因祸得福"得以伸展的情景. ...
- linux 内核源代码情景分析——linux 内核源码中的汇编语言代码
1. 用汇编语言编写部分核心代码的原因: ① 操作系统内核中的底层程序直接与硬件打交道,需要用到一些专用的指令,而这些指令在C语言中并无对应的语言成分: ② CPU中的一些特殊指令也没有对应的C语言成 ...
- Linux内核源代码情景分析-中断半
一.中断初始化 1.中断向量表IDT初始化 void __init init_IRQ(void) { int i; #ifndef CONFIG_X86_VISWS_APIC init_ISA_irq ...
随机推荐
- # Zombie Gunship Survival(僵尸炮艇生存)GG修改器修改教程
Zombie Gunship Survival(僵尸炮艇生存)GG修改器修改教程 1.修改伤害,打击范围,武器冷却时间,子弹容量 测试手机机型:华为畅享7 系统版本:Android7.0 是否ROOT ...
- 我下载了python所有包,用以备份,有需要的自提
1.背景 我最近准备把1985年-2019年的全国30m分辨率土地利用数据按照地级市进行裁剪与归纳,这需要用到Geopandas对shp数据进行批量操作.在安装Geopandas的python包时,遇 ...
- git合并内容的1个方式
诉求 把自己的改动的文件合并到目标分支: 不想改那些不属于自己开发时出现的冲突: 操作 开发分支dev,要合并至master分支 1 所有改动都已提交,保持分支的干净状态(working tree c ...
- sonar扫描java项目报错
安装maven 配置path 验证maven,看到以下信息证明已经成功 扫描项目 扫描以下项目: kf-buss-nhgip-smartoffice-business-thirdparty 项目的配置 ...
- jmeter 录制排除模式
jmeter录制时,静态的资源不需要,可以在录制的时候直接排除. .*\.(bmp|css|js|gif|icov|jpeg|png|swf|woff|woff2|htm|html).* .*\.(j ...
- ios web 媒体查询兼容
原文:https://blog.csdn.net/dear_zx/article/details/82785250 防止链接丢失,复制一下 兼容iphone4/4s: @media (device-h ...
- P3313-[SDOI2014]旅行【树链剖分,线段树】
正题 题目链接:https://www.luogu.com.cn/problem/P3313 题目大意 \(n\)个点的一棵树,每个点有一个颜色和权值,有操作 修改一个点的权值 修改一个点的颜色 询问 ...
- Spring Security 学习+实践
Spring Security是Spring为解决应用安全所提供的一个全面的安全性解决方案.基于Spring AOP和Servlet过滤器,启动时在Spring上下文中注入了一组安全应用的Bean,并 ...
- php链接mysql,php链接mysql的常用方法
PHP连接MySQL数据库的几种方法 1.最简单的方式-mysql(面向过程) <?php $con = mysql_connect("localhost","ro ...
- 国内首篇云厂商 Serverless 论文入选全球顶会:突发流量下,如何加速容器启动?
作者 | 王骜 来源 | Serverless 公众号 导读 USENIX ATC (USENIX Annual Technical Conference) 学术会议是计算机系统领域的顶级会议,入 ...