一、CPU如何执行程序?
提纲
- 图灵机工作方式
- 冯诺依曼模型
- 线路位宽CPU位宽
- 程序执行基本过程
- 执行具体过程
1. 图灵机工作方式
图灵机可以视作“一台带规则的自动草稿机”
图灵机基本组成:
-
纸带(内存):连续格子组成,每个格子写入字符,纸带好比内存,格子上的字符好比内存中的程序与数据;
-
读写头:一支笔,能读格子、改符号、左右移动。
-
状态表:一本规则手册,
-
控制器:负责对照规则表,自动执行上面操作。
-
工作过程:循环 “看→改→移→换状态”
从 初始状态 开始,重复以下步骤: -
① 读:读写头看当前格子的符号(比如 1);
-
② 查规则:根据当前状态和符号,查状态表,得到三个指令(改什么符号、往哪移、变啥状态);
-
③
改 + 移:按指令改符号、移动读写头; ④ 换状态:切换到新状态,回到步骤①,直到碰到 终止状态 停下。
总的来说,图灵机计算1+2的过程。图灵机的主要功能就是读取纸带格子中的内容,交给控制单元识别字符是数字还是运算符,如果是数字存入状态器,如果是运算符,则通知运算符单元读取状态中的数值进行计算,计算结果最终返回给读写头,读写头将结果写入到纸袋的格子中。
2.冯诺依曼模型
1945年冯诺依曼遵循图灵机设计,提出用电子元件构建计算机,并约定二进制进行计算和存储。
冯诺依曼计算机基本结构有5个重要部分,运算器、控制器、存储器、输入设备和输出设备。
运算器、控制器是在中央处理器中,存储器就是内存,输入输出都是计算机外设,比如鼠标键盘是输入设备,显示器是输出设备。
内存
计算机的程序和数据都存储在内存中,存储基本单位是字节(byte),1字节等于8位(8 bit)。每个字节对应一个内存地址。
存储区域线性,指内存地址从0开始编号,自增排序,类似数组,最后一个地址为内存总字节数-1,因此内存读写任何一个数据的速度是一样的。
中央处理器
中央处理器即CPU,32位CPU和64位CPU区别在于一次能计算多少字节数据:
- 32位CPU一次可以计算4字节;
- 64位CPU一次可以计算8字节;
32 位和 64 位,通常称为 CPU 的位宽,代表的是 CPU 一次可以计算(运算)的数据量。
32 位和 64 位,通常称为 CPU 的位宽,代表的是 CPU 一次可以计算(运算)的数据量。如果是 8 位的 CPU,那么一次只能计算 1 个字节(0-255)范围内的数值,这样就无法完成一次10000 * 500
总线
输入输出
Linux内核 vs Windows内核
内核
内核是什么?[应用与硬件设备交互的中间桥梁]
计算机由外部硬件设备构成,CPU、内存、硬盘等,如果每个应用都要和这些硬件对接通信协议就太麻烦!所以需要一个“中间人”,统一对接应用和计算机硬件。内核就是应用连接硬件设备的桥梁,应用只关心如何与内核交互,不用关心硬件细节!
内核有什么能力?
- 进程调度:
- 管理进程线程,决定哪个进程线程用CPU;
- 内存管理:
- 管理内存,决定内存分配与回收;
- 硬件通信:
- 管理硬件设备,为进程与硬件设备之间提供通信功能;
- 系统调用:
- 提供系统调用,如果应用程序需要运行更高权限的服务,就需要用到系统调用,是用户程序与操作系统之间的接口;
内核如何工作?
内核权限高,可以直接控制CPU、内存、硬盘等硬件设备,而应用程序权限很小,因此操作系统把内存分为两个区域:
- 内核空间:这个内存空间只有内核程序可以访问。
- 用户空间:这个内存空间专门给应用程序使用;
内核空间的代码可以访问所有内存空间,用户空间的代码只能访问一个局部的内存空间。
因此,当程序使用用户空间的时候,我们称该程序在用户态执行;程序使用内核空间时,程序在内核态运行。
应用程序如果需要进入内核空间,就需要系统调用实现:
系统调用与中断:
正常情况下,内核程序执行在内核态,用户程序执行在用户态。当应用程序使用系统调用时,会产生一个中断,发送中断后,CPU会中断当前执行中的用户程序,转而跳转到中断处理程序,也就是开始执行内核程序,内核程序处理完毕后,主动触发中断,把CPU执行权限交回用户程序,回到用户态继续工作。
Linux的设计
Linux诞生于1991年,芬兰小伙子C语言实现。
Linux设计理念:
- MultiTask,多任务;
- SMP,对称多处理;
- ELF,可执行文件链接格式;
- Monolithic Kernel,宏内核;
MultiTask
Linux是个多任务操作系统,可以有多个任务同时(并发 / 并行)进行。
- 并发:单核CPU,轮流处理多个任务,每个任务处理一段时间就切换执行另一个任务,宏观上同时处理多个任务;
- 并行:多核CPU,多个CPU核心真正同时处理多个任务;
SMP
Linux具有对称多处理特性,代表每个CPU地位相等,具体的:
- 资源使用权限相同;
- 多CPU共享同个内存;
- 每个CPU都可以访问完整的内存和硬件资源;
不存在Linux某个程序单独服务某个应用或者内核程序,每个程序都可以被分配到任意一个CPU执行。
ELF
ELF(Executable and Linkable Format,可执行与可链接格式)是 Linux 系统中最常用的二进制文件格式,简单说,它就像一个 “统一的包装盒”,能装下程序编译、链接、运行过程中需要的各种二进制数据(比如代码、数据、符号等),并且让系统和工具(编译器、链接器、操作系统)能 “看懂” 里面的内容。
它的核心特性可以通俗理解为:
- “一包多用” 的通用性
- 同一个格式能装多种类型的文件:比如编译中间产生的目标文件(.o)、最终能直接运行的可执行文件、共享库(.so,类似 Windows 的.dll),甚至程序崩溃时的核心转储文件(core dump)。不用为不同类型的二进制文件设计多种格式,简化了系统处理逻辑。
- “结构化打包” 的灵活性
ELF 文件内部像 “分层抽屉”:
- 最外层有个 “标签页”(ELF头部),记录文件类型(是可执行文件还是库)、适配的 CPU 架构(x86/ARM 等)、入口地址(程序从哪开始跑)等关键信息。
- 里面的内容按 “用途” 分区域放:比如
“代码区”(.text,存程序指令)、“数据区”(.data,存初始化的变量)、“符号表”(.symtab,存函数 /
变量的名字和地址)等。 这些区域在 “打包”(链接阶段)时按 “节(Section)” 划分,在 “拆包运行”(加载到内存)时按
“段(Segment)” 划分,既方便编译器链接,又方便操作系统加载到内存。
- “跨设备兼容” 与 “可扩展”
它不挑 CPU 架构,只要在 “标签页” 里注明适配的架构(比如 x86 或 ARM),不同设备都能识别。而且如果以后有新需求(比如加新类型的数据),可以在 “抽屉” 里加新的区域,不影响原有结构,扩展性很强。 - “按需加载” 的动态链接支持
比如我们写程序时用了系统库(如 printf 函数),ELF 能让程序不把库代码 “打包”
进自己的文件里,而是在运行时通过 “动态链接器”(类似 “快递员”)临时加载系统里的共享库(.so)。这样既节省内存(多个程序共用一个库),又方便库更新(改库不用重新编译所有程序)。 - “清晰的符号管理” 程序里的函数名、变量名(比如 “add 函数”“count 变量”),在 ELF 里会被记录在 “符号表” 中,像 “通讯录” 一样,告诉编译器 / 链接器 “这个名字对应哪个地址”,确保程序运行时能正确找到要用的函数或变量。
总之,ELF 的核心是 “统一、灵活、兼容”,让 Linux 系统里的二进制文件从编译到运行的全流程都能被高效处理,是 Linux 程序能正常工作的 “幕后功臣”。
ELF 文件有两种索引,Program header table 中记录了运行时所需要的段,而Section header table 记录了二进制文件中的各个段的首地址。
ELF如何生成?
我们编写的代码,首先通过编译器编译成汇编代码,接着通过汇编器编程目标代码,也就是目标文件,最后通过链接器把多个目标文件以及调用的各自函数库链接起来,形成可执行文件即ELF。
ELF如何被执行呢?
执行ELF文件时,会通过装载器把ELF文件装载在内存中,CPU读取内存中的指令和数据,程序就被执行起来了。
Monolithic Kernel
Monolithic Kernel 即宏内核,是操作系统内核一种经典架构:把操作系统所有核心功能(比如进程管理、内存分配、文件系统、设备驱动、中断处理等)都打包在一个单一的内核程序里,并且认为它们都运行在最高权限的“内核态”。
宏内核的核心特征:
- “大一统”结构:不像微内核(Microkernel)那样把功能拆成多个独立模块,宏内核里所有关键组件都 “挤” 在同一个内存空间里,彼此直接通信(比如函数调用),不需要复杂的跨进程交互。
- 效率优先:因为组件间通信直接,没有额外的权限切换或消息传递开销,所以性能通常比较高(比如进程调度、内存访问更快)。
- 依赖内核态特权:所有核心功能都运行在 “内核态”(操作系统的最高权限模式),能直接访问硬件资源,省去了用户态与内核态切换的成本。
优缺点:
- 优点:性能好,响应快,适合对效率敏感的场景(比如服务器、桌面系统)。
- 缺点:内核体积大、结构复杂,修改或维护某个功能(比如加一个新设备驱动)可能需要重新编译整个内核;而且一个组件出问题(比如驱动崩溃)可能导致整个内核崩溃。
与之相对的是微内核(Microkernel)
核心思路是极简核心+外部服务:
只把操作系统最底层、最必要的功能(进程调度、内存基础管理、进程之间消息传递)放进内核态,其他功能(文件系统、设备驱动、网络协议)都做成独立的服务进程,跑在用户态。
混合内核(Hybrid Kernel)
核心思路是“取两者之长”:
保留微内核的精简核心框架,但是把一些常用的关键服务(文件系统、设备驱动)挪到内核态,减少消息传递的开销。
既不会像微内核那样,所有非核心功能都在用户态,可以避免性能损失。也不会像宏内核那样所有功能都挤在核内,保证了一定模块化。
- 优点:平衡了模块化设计与性能需求;
Windows设计
当今Windows7/10使用的内核叫做Windows NT,全称New Technology。
与Linux异同点:
- 相同:
- 多任务
- 对称多处理
- 不同:
- 混合型内核:
- 可执行文件:PE,可移植执行文件
总结
内核架构:
- 宏内核:包含多个模块,整个像一个完整的程序都运行在内核态。
- 微内核:有一个最小版本的内核只负责最重要的功能,一些模块和服务则有用户态管理。
- 混合内核:是宏内核和微内核的结合,内核中抽象出了微内核的概念,也就是内核中有一个小型的内核,其他模块在这个基础上搭建,整个内核就是个完整的程序。
Linux采用了宏内核设计,Windows采用了混合内核设计。
两个操作系统的可执行文件是最大差异,Linux是ELF,Windows是PE.