一、对程序员来说CPU是什么

407 阅读6分钟

CPU的内部结果解析

CPU, 中央处理器, 所负责的就是解释和运行的最终转换成机器语言的程序内容


程序运行流程:
image.png

CPU和内存都是由许多晶体管组成的电子元件, 通常称为IC(Integral Circuit, 集成电路), 从功能上看, **CPU内部由寄存器、控制器、运算器、时钟四部分构成.**各部分之间由电流信号相互连通.

寄存器: 可以用来暂存指令, 数据等处理对象, 可以看作内存的一种
控制器: 负责把内存上的指令,数据读入寄存器, 并根据指令的执行结果来控制整个计算机
运算器: 负责运算从内存读入寄存器的数据
时钟: 负责发出CPU开始计时的时钟信号, 不过有些时钟位于CPU的外部

image.png

内存(主存): 主存通过控制芯片等与 CPU 相连, 主要负责存储指令和数据。主存由可读写的元素构成,每个字节(1 字节 = 8 位 )都带有一个地址编号。

CPU 可以通过该地址读取主存中的 指令和数据,当然也可以写入数据。但有一点需要注意,主存中存储 的指令和数据会随着计算机的关机而自动清除。

补充:

  • 程序: 是指计算机每一步动作的一组指令, 由指令和数据组成
  • 机器语言: 可以被CPU直接识别并使用的语言
  • 时钟信号英文叫作 clock puzzle。Pentium 2 GHz 表示时钟信号的频率为 2 GHz(1 GHz = 10 亿次 / 秒)。也就是说,时钟信号的频率越高,CPU 的 运行速度越快。

CPU是寄存器的集合


不同类型的 CPU,其内部寄存器的数量、种类以及寄存器存储的 数值范围都是不同的, 根据功能的不同,我们可以将寄存器大 致划分为八类

image.png
可以看出,寄存器中存储的内容既可以 是指令也可以是数据。数据分为“用于运算的数值”和“表示内存地址的数值”两种。

数据种类不同,存储该数值的寄存器也不同。 CPU 中每个寄存器的功能都是不同的。用于运算的数值放在累加寄存器中存储,表示内存地址的数值则放在基址寄存器和变址寄存器中 存储。

其中,程序计数器、累加寄存器、标志寄存器、指令寄存器和栈寄存器都只有一个,其他的寄存器一般有多个。

决定流程的程序计数器


假设地址 0100 是程序运行的开始位置。Windows 等操作系统把程序从硬盘复制到内存后,会将程序计数器(CPU 寄存器的一种)设定为0100,然后程序便开始运行。CPU 每执行一个指令,程序计数器的值 就会自动加 1。然后,CPU 的控制器就会参照程序计数器的数值,从内存中读取命令并执行。也就是说,程序计数器决定着程序的流程。
image.png

条件分支和循环机制

程序的流程分为顺序执行、条件分支和循环三种。顺序执行是指按照地址内容的顺序执行指令。条件分支是指根据条件执行任意地址的指令。循环是指重复执行同一地址的指令


例如, 把内存中存储的数值(示例中是 123)的绝对值输出到 显示器的程序的内存状态。程序运行的开始位置是 0100 地址。

随着程 序计数器数值的增加,当到达 0102 地址时,如果累加寄存器的值是正数,则执行跳转指令(jump 指令)跳转到 0104 地址。

此时,由于累加 寄存器的值是 123,为正数,因此 0103地址的指令被跳过,程序的流程直接跳转到了 0104 地址(执行jump指令)。也就是说,“跳转到 0104 地址”这个指令间接执行了“将程序计数器设定成 0104 地址”这个操作。
image.png
无论当前累加寄存器的运算结果是负数、零还是正数,标志寄存器都会将其保存(也负责存放溢出 A 和奇偶校验 B 的结果 )。

CPU 在进行运算时,标志寄存器的数值会根据运算结果自动设定。 至于是否执行跳转指令,则由CPU 在参考标志寄存器的数值后进行判断。运算结果的正、零、负 三种状态由标志寄存器的三个位表示。
image.png

函数的调用机制

函数调用处理也是通过把程序计数器的值设定成函数的存储地址来实现的.函数的调用需要在完成函数内部的处理后,处理流程再返回到函数调用点(函数调用指令的下一个地址).


单纯的跳转指令只能跳转到函数路口,当函数执行完了却无法返回被调用处了

给变量 a 和 b 分别代入 123 和 456 后,将其赋值给参数 (parameter)来调用 MyFunc 函数的 C 语言程序。

函数调用时使用call指令, 将函数的入口地址设置到程序计数器之前, call指令会把函数调用后要执行的指令地址存储在栈的主内存中,等函数处理完后通过return指令, 把保存到栈中的地址保存到程序计数器中
image.png
image.png

补充:

  • 32 位 CPU 指的就是用 32 位的二进制数来表示数据及地址的数值。

通过地址和索引实现数组

我们可以通过基址寄存器和变址寄存器,对主内存上的特定内存区域进行划分, 从而实现类似数组操作


首先,我们用十六进制数 B 将计算机内存上 00000000~FFFFFFFF 的地址划分出来。那么,凡是该范围的内存区域,只要有一个 32 位的 寄存器,即可查看全部的内存地址。但如果想要像数组那样分割特 定的内存区域以达到连续查看的目的,使用两个寄存器会更方便些。

例如,查看 10000000 地址~1000FFFF 地址时,如图 1-9 所示, 可 以 将 10000000 存 入 基 址 寄 存 器, 并 使 变 址 寄 存 器 的 值 在 00000000~0000FFFF 变化。CPU 则会把基址寄存器+变址寄存器的值 解释为实际查看的内存地址。变址寄存器的值就相当于高级编程语言 程序中数组的索引功能。
image.png

CPU的处理很简单


按照功能对 CPU 能执行的机器语言指令进行了大体分类。虽然高级编程语言编写的程序看起来非常复杂,但 CPU 实际处理的事情就是这么简单。
image.png

参考: