共计 2820 个字符,预计需要花费 8 分钟才能阅读完成。
本文丸趣 TV 小编为大家详细介绍“Linux 的底层体系结构是怎样的”,内容详细,步骤清晰,细节处理妥当,希望这篇“Linux 的底层体系结构是怎样的”文章能帮助大家解决疑惑,下面跟着丸趣 TV 小编的思路慢慢深入,一起来学习新知识吧。
计算机的工作模式
对于一个计算机来说,最核心的是 CPU,CPU 是计算机的大脑,所有设备都围绕其展开
CPU 通过总线 (Bus) 与其他设备连接,在这些设备中,最为重要的是内存(Memory)
单靠 CPU 是无法完成计算任务的,很多复杂的计算任务都需要将中间结果保存下来,然后基于中间结果进行下一步的计算
CPU 和内存是完成计算的核心组件
CPU 本身无法保存这么多的中间结果,因此需要依赖于内存
CPU
CPU 包含三部分:运算单元、数据单元和控制单元
运算单元只管计算,但它不知道应该算哪些数据,运算结果应该放在哪里
运算单元计算的数据如果每次都要经过总线,直接到内存里面现拿,速度会很慢,因此出现了数据单元
数据单元包括 CPU 内部的缓存和寄存器组,空间很小,但速度很快
控制单元是一个统一的指挥中心,可以获得下一条指令,然后执行这条指令
这个指令会指导运算单元取出数据单元中的某几个数据,计算出结果,然后放在数据单元的某个地方
计算过程
1. 每个进程都有一个程序放在硬盘上,是二进制的,在里面存储的是一行一行的指令,这些指令会操作一些数据
2. 进程开始运行,会有独立的内存空间,相互隔离但不连续 – 程序会分别加载到进程 A 和进程 B 的内存空间里面,形成各自的代码段
3. 程序在运行过程中要操作的数据和产生的计算结果,都会放在数据段 (内存) 里
4. 在 CPU 的控制单元里面,有一个指令指针寄存器,记录的是下一条指令在内存中的地址 – 控制单元会不停地将代码段的指令拿进来,先放入指令寄存器
5. 指令的组成部分:做什么操作 + 操作哪些数据 – 要执行指令,需要将 *** 部分交给运算单元,将第二部分交给数据单元
6. 数据单元根据数据的地址,从数据段里读取数据到数据寄存器,最终会有指令将数据写回到内存中的数据段
7. CPU 里有两个寄存器,专门保存当前处理进程的代码段起始地址和数据段起始地址,图中的当前进程为进程 A
8. CPU 和内存通过总线传输数据,总线上有两类数据 – 地址总线(Address Bus):地址数据,位数决定了能访问的地址有多广 – 数据总线(Data Bus):真正的数据,位数决定了一次性能拿多少数据
x86 架构
型号
8086 的原理
通用寄存器
为了暂存数据,8086 处理器内部有 8 个 16 位的通用寄存器,属于 CPU 内部的数据单元
分别是 AX、BX、CX、DX、SP、BP、SI 和 DI
其中 AX、BX、CX 和 DX 可以分成两个 8 位的寄存器来使用,其中 H 就是 High,L 就是 Low
这样,比较长的数据也能暂存,比较短的数据也能暂存
控制单元
IP 寄存器 (Instruction Pointer Register) 即指令指针寄存器
– 指向代码段中下一条指令的位置
– CPU 会根据 IP 寄存器不断地将指令从内存的代码段中,加载到 CPU 的指令队列中,然后交给运算单元去执行
切换进程
– 每个进程都分为代码段和数据段
– 为了指向不同进程的地址空间,有 4 个 16 位的段寄存器,分别是 CS、DS、SS 和 ES
CS(Code Segment Register)是代码段寄存器,通过它可以找到代码在内存中的位置
DS(Data Segment Register)是数据段寄存器,通过它可以找到数据在内存中的位置
SS(Stack Segment Register)是栈寄存器,但凡与函数调用相关的操作,都与栈紧密相关
– A 调用 B,B 调用 C
– 当 A 调用 B 的时候,要执行 B 函数的逻辑,因而 A 运行的相关信息会被 push 到栈里
– 当 B 调用 C 的时候,同理,B 运行的相关信息会被 push 到栈里,然后才运行 C 函数的逻辑
– 当 C 运行完毕后,先 pop 出来的是 B,B 接着调用 C 函数之后的指令运行下去
– B 运行完毕后,再 pop 出来的是 A,A 接着运行,直至结束
加载内存数据
如果需要加载内存中的数据,可以通过 DS 找到内存中的数据,加载到通用寄存器
对于一个段,有一个起始地址,而段内的具体位置,称为偏移量
CS 和 DS 都存放着一个段的起始地址
代码段的偏移量放在 IP 寄存器
数据段的偏移量放在通用寄存器
CS 和 DS 都是 16 位的(起始地址),IP 寄存器和通用寄存器也都是 16 位的(偏移量),但 8086 的地址总线是 20 位的
凑 20 位:起始地址 4 + 偏移量
无论真正的内存有多大,对于只有 20 位地址总线的 8086 来说,能够区分的地址也就 2^20=1M(寻址单位为 Byte)
如果想访问 1M+ X 的地方,在总线上超过 20 位的部分根本发不出去,*** 访问的还是 1M 内的 X 位置
偏移量只有 16 位的,所以一个段的 *** 大小为 2^16=64K
因此对于 8086 的 CPU 来说,最多只能访问 1M 的内存空间,还要分成多个段,每个段 *** 为 64K
32 位处理器
在 32 位的 CPU 中,有 32 根地址总线,可以访问 2^32=4G 的内存
x86 架构是开放的,因此 32 位的 CPU 需要兼容原来的架构
兼容
1. 通用寄存器 – 将 8 个 16 位的通用寄存器扩展到 8 个 32 位的通用寄存器,但依然保留 16 位和 8 位的使用方式 – 高 16 位不能分成两个 8 位使用,因为这是不兼容的
2. IP 寄存器 – 指向下一条指令的指令指针寄存器 IP,会扩展成 32 位的,同样兼容 16 位
3. 段寄存器(Segment Register) – CS、DS、SS 和 ES 仍然是 16 位,但不再是段的起始地址,段的起始地址放在内存的某个地方(表格)
– 表格中的一项是段描述符(Segment Descriptor),里面才是段真正的起始地址 – 而段寄存器里面保存的是这个表格中的某一项,称为选择子(Selector)
– 获取段起始地址的流程:先间接地从段寄存器中找到表格中的一项,再从表格中的一项拿到段真正的起始地址
– 为了快速拿到段的起始地址,段寄存器会从内存中拿到 CPU 的描述符高速缓存器中
– 这种模式与 8086 的模式不兼容,但非常灵活,可以保持未来的兼容性
实模式 VS 保护模式
在 32 位的架构下,将前一种模式称为实模式(Real Pattern),后一种模式称为保护模式(Protected Pattern)
系统刚刚启动的时候,CPU 处于实模式,此时和原来的模式是兼容的。即 32 位的 CPU,也支持在原来的模式下运行,速度会快一点
当需要更多内存时,可以遵循一定的规则,进行一系列的操作,然后切换到保护模式,就能够用到 32 位 CPU 更强大的能力
如果不能无缝兼容,但通过切换模式兼容,也是可以接受的
系统交互
常用汇编指令
mov, call, jmp, int, ret, add, or, xor, shl, shr, push, pop, inc, dec, sub, cmp
读到这里,这篇“Linux 的底层体系结构是怎样的”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注丸趣 TV 行业资讯频道。