0717-7821348
爱彩人网

爱彩人网

您现在的位置: 首页 > 爱彩人网
爱彩人网-Linux后端程序生长关键技术---底层体系结构
2019-07-01 23:07:14

核算机程序的Bug千奇百怪,要想能顺畅的处理疑难杂症,有必要对核算机的底层原理十分了解。比如在实践生产中不但咱们的运用会出问题,操作体系也可能有Bug,硬件也可能有Bug。因而,只要愈加深化的理解了原理,才干愈加便利咱们处理问题。

本文对核算机的体系结构底层原理进行扼要的介绍。这些常识关于协助咱们处理疑难问题会有很大的协助。做程序开发应该深化原理,不只要知其然,还要知其所以然。

核算机的作业形式

  1. 关于一个核算机来说,最中心的是CPU,CPU是核算机的大脑,一切设备都环绕其打开
  2. CPU经过总线(Bus)与其他设备衔接,在这些设备中,最为重要的是内存(Memory)
  3. 单靠CPU是无法完结核算使命的,许多杂乱的核算使命都需求将中心成果保存下来,然后依据中心成果进行下一步的核算
  4. CPU和内存是完结核算的中心组件

CPU自身无法保存这么多的中心成果,因而需求依赖于内存

CPU

  1. CPU包含三部分:运算单元、数据单元和操控单元
  2. 运算单元只管核算,但它不知道应该算哪些数据,运算成果应该放在哪里
  3. 运算单元核算的数据假如每次都要经过总线,直接到内存里边现拿,速度会很,因而呈现了数据单元
  4. 数据单元包含CPU内部的缓存寄存器组,空间很小,但速度很快
  5. 操控单元是一个一致的指挥中心,能够获得下一条指令,然后履行这条指令

这个指令会辅导运算单元取出数据单元中的某几个数据,核算出成果,然后放在数据单元的某个当地

核算进程

1. 每个进程都有一个程序放在硬盘上,是二进制的,在里边存储的是一行一行的指令,这些指令会操作一些数据

2. 进程开端运转,会有独立的内存空间,彼此阻隔但不接连 - 程序会分别加载到进程A和进程B的爱彩人网-Linux后端程序生长关键技术---底层体系结构内存空间里边,构成各自的代码段

3. 程序在运转进程中要操作的数据和发生的核算成果,都会放在数据段(内存)里

4. 在CPU的操控单元里边,有一个指令指针寄存器,记载的是下一条指令在内存中的地址 - 操控单元会不停地将代码段的指令拿进来,先放入指令寄存器

5. 指令的组成部分:做什么操作 + 操作哪些数据 - 要履行指令,需求将榜首部分交给运算单元,将第二部分交给数据单元

6. 数据单元依据数据的地址,从数据段里读取数据到数据寄存器,终究会有指上原miku令将数据写回到内存中的数据段

7. CPU里有两个寄存器,专门保存当时处理进程代码段开始地址数据段开始地址,图中的当时进程为进程A

8. CPU和内存经过总线传输数据,总线上有两类数据 - 地址总线(Address Bus):地址数据,位数决议了能拜访的地址有多广 - 数据总线(Data Bus):真实的数据,位数决议了一次功能拿多少数据

x86架构

类型

8086的原理

通用寄存器

  1. 为了暂存数据,8086处理器内部有8个16位的通用寄存器,归于CPU内部的数据单元
  2. 分别是AX、BX、CX、DX、SP、BP、SI和DI
  3. 其间AX、BX、CX和DX能够分红两个8位的寄存器来运用,其间H便是High,L便是Low
  4. 这样,比较长的数据也能暂存,比较短的数据也能暂存

操控单元

  • 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出来爱彩人网-Linux后端程序生长关键技术---底层体系结构的是A,A接着运转,直至完毕

加载内存数据

  1. 假如需求加载内存中的数据,能够经过DS找到内存中的数据,加载到通用寄存器
  2. 关于一个段,有一个开始地址,而段内的具体方位,称为偏移量
  3. CS和DS都存放着一个段的开始地址
  • 代码段的偏移量放在IP寄存器
  • 数据段的偏移量放在通用寄存器
  1. CS和DS都是16位的(开始地址),IP寄存器和通用寄存器也都是16位的(偏移量),但8086的地址总线是20位的
  • 凑20位:开始地址 << 4 + 偏移量
  1. 不管真实的内存有多大,关于只要20位地址总线的8086来说,能够区别的地址也就2^20=1M(寻址单位为Byte
  • 假如想拜访1M+X的当地,在总线上超越20位的部分底子发不出去,最终拜访的仍是1M内的X方位
  1. 偏移量只要16位的,所以一个段的最大巨细为2^16=64K
  2. 因而关于8086的CPU来说,最多只能拜访1M的内爱彩人网-Linux后端程序生长关键技术---底层体系结构存空间,还要分红多个段,每个段最大为64K

32位处理器

  1. 在32位的CPU中,有32根地址总线,能够拜访2^32=4G的内存
  2. x86架构是敞开的,因而32位的CPU需求兼容本来的架构

兼容

1. 通用寄存器 - 将8个16位的通用寄存器扩展到8个32位的通用寄存器,但仍然保存16位和8位的运用方法 - 高16位不能分红两个8位运用,由于这是不兼容

2. IP寄存器 - 指向下一条指令爱彩人网-Linux后端程序生长关键技术---底层体系结构的指令指针寄存器IP,会扩展成32位的,相同兼容16位

3. 段寄存器(Segment Register) - CS、DS、SS和ES仍然是16位,但不再是段的开始地址,段的开始地址放在内存的某个当地(表格

- 表格中的一项是段描述符(Segment Descriptor),里边才是段真实的开始地址 - 而段寄存器里边保存的是这个表格中的某一项,称为挑选子(Selector)

- 获取段开始地址的流程:先直接地从段寄存器中找到表格中的一项,再从表格中的一项拿到段真实的开始地址

- 为了快速拿到段的开始地爱彩人网-Linux后端程序生长关键技术---底层体系结构址,段爱彩人网-Linux后端程序生长关键技术---底层体系结构寄存器会从内存中拿到CPU的描述符高速缓存器

- 这种形式与8086的形式不兼容,但十分灵敏,能够坚持未来的兼容性

实形式 VS 保护形式

  1. 在32位的架构下,将前一种形式称为实形式(Real Pattern),后一种形式称为保护形式(Protected Pattern)
  2. 体系刚刚发动的时分,CPU处于实形式,此刻和本来的形式是兼容的。即32位的CPU,也支撑在本来的形式下运转,速度会快一点
  3. 当需求更多内存时,能够遵从必定的规矩,进行一系列的操作,然后切换到保护形式,就能够用到32位CPU更强壮的才能
  4. 假如不能无缝兼容,但经过切换形式兼容,也是能够承受

体系交互

常用汇编指令

mov, call, jmp, int, ret, add, or, xor, shl, shr, push, pop, inc, dec, sub, cmp

本文作者: zhongmingmao

本文链接: http://zhongmingmao.me/2019/04/09/linux-x86/