Linux后端程序成长关键技术之底层体系结构,


计算机程序的Bug千奇百怪,要想能顺利的解决疑难杂症,必须对计算机的底层原理非常熟悉。比如在实际生产中不光我们的应用会出问题,操作系统也可能有Bug,硬件也可能有Bug。因此,只有更加深入的理解了原理,才能更加方便我们解决问题。

本文对计算机的体系结构底层原理进行简要的介绍。这些知识对于帮助我们解决疑难问题会有很大的帮助。做程序开发应该深入原理,不仅要知其然,还要知其所以然。

计算机的工作模式

Linux后端程序成长关键技术---底层体系结构

CPU本身无法保存这么多的中间结果,因此需要依赖于内存

CPU

这个指令会指导运算单元取出数据单元中的某几个数据,计算出结果,然后放在数据单元的某个地方

计算过程

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

2. 进程开始运行,会有独立的内存空间,相互隔离但不连续 - 程序会分别加载到进程A和进程B的内存空间里面,形成各自的代码段

3. 程序在运行过程中要操作的数据和产生的计算结果,都会放在数据段(内存)里

Linux后端程序成长关键技术---底层体系结构

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

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

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

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

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

x86架构

型号

Linux后端程序成长关键技术---底层体系结构

8086的原理

Linux后端程序成长关键技术---底层体系结构

通用寄存器

控制单元

  • 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接着运行,直至结束

Linux后端程序成长关键技术---底层体系结构

加载内存数据

  • 代码段的偏移量放在IP寄存器
  • 数据段的偏移量放在通用寄存器
  • 凑20位:起始地址 << 4 + 偏移量
  • 如果想访问1M+X的地方,在总线上超过20位的部分根本发不出去,最后访问的还是1M内的X位置

32位处理器

兼容

Linux后端程序成长关键技术---底层体系结构

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 保护模式

系统交互

Linux后端程序成长关键技术---底层体系结构

常用汇编指令

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

相关内容