0
点赞
收藏
分享

微信扫一扫

4、程序执行的基本过程

1、程序在图灵机的执行过程:

4、程序执行的基本过程_数据

图灵机的基本组成如下:

  • 有一条「纸带」,纸带由一个个连续的格子组成,每个格子可以写入字符,纸带就好比内存,而纸带上的格子的字符就好比内存中的数据或程序;
  • 有一个「读写头」,读写头可以读取纸带上任意格子的字符,也可以把字符写入到纸带的格子;
  • 读写头上有一些部件,比如存储单元、控制单元以及运算单元: 1、存储单元用于存放数据; 2、控制单元用于识别字符是数据还是指令,以及控制程序的流程等; 3、运算单元用于执行运算指令;

知道了图灵机的组成后,我们以简单数学运算的 ​​1 + 2​​ 作为例子,来看看它是怎么执行这行代码的。

  • 首先,用读写头把 「1、2、+」这 3 个字符分别写入到纸带上的 3 个格子,然后读写头先停在 1 字符对应的格子上;

4、程序执行的基本过程_数据_02

  • 接着,读写头读入 1 到存储设备中,这个存储设备称为图灵机的状态;

4、程序执行的基本过程_数据_03

  • 然后读写头向右移动一个格,用同样的方式把 2 读入到图灵机的状态,于是现在图灵机的状态中存储着两个连续的数字, 1 和 2;

4、程序执行的基本过程_数据_04

  • 读写头再往右移动一个格,就会碰到 + 号,读写头读到 + 号后,将 + 号传输给「控制单元」,控制单元发现是一个 + 号而不是数字,所以没有存入到状态中,因为​​+​​ 号是运算符指令,作用是加和目前的状态,于是通知「运算单元」工作。运算单元收到要加和状态中的值的通知后,就会把状态中的 1 和 2 读入并计算,再将计算的结果 3 存放到状态中;

4、程序执行的基本过程_寄存器_05

  • 最后,运算单元将结果返回给控制单元,控制单元将结果传输给读写头,读写头向右移动,把结果 3 写入到纸带的格子中;

4、程序执行的基本过程_寄存器_06

通过上面的图灵机计算 ​​1 + 2​​ 的过程,可以发现图灵机主要功能就是读取纸带格子中的内容,然后交给控制单元识别字符是数字还是运算符指令,如果是数字则存入到图灵机状态中,如果是运算符,则通知运算符单元读取状态中的数值进行计算,计算结果最终返回给读写头,读写头把结果写入到纸带的格子中。


2、程序在冯诺依曼模型上的执行过程:

​程序实际上是一条一条指令,所以程序的运行过程就是把每一条指令一步一步的执行起来,负责执行指令的就是 CPU 了。

4、程序执行的基本过程_寄存器_07

那 CPU 执行程序的过程如下:

  • 第一步,CPU 读取「程序计数器」的值,这个值是指令的内存地址,然后 CPU 的「控制单元」操作「地址总线」指定需要访问的内存地址,接着通知内存设备准备数据,数据准备好后通过「数据总线」将指令数据传给 CPU,CPU 收到内存传来的数据后,将这个指令数据存入到「指令寄存器」。
  • 第二步,CPU 分析「指令寄存器」中的指令,确定指令的类型和参数,如果是计算类型的指令,就把指令交给「逻辑运算单元」运算;如果是存储类型的指令,则交由「控制单元」执行;
  • 第三步,CPU 执行完指令后,「程序计数器」的值自增,表示指向下一条指令。这个自增的大小,由 CPU 的位宽决定,比如 32 位的 CPU,指令是 4 个字节,需要 4 个内存地址存放,因此「程序计数器」的值会自增 4;

简单总结一下就是,一个程序执行的时候,CPU 会根据程序计数器里的内存地址,从内存里面把需要执行的指令读取到指令寄存器里面执行,然后根据指令长度自增,开始顺序读取下一条指令。

CPU 从程序计数器读取指令、到执行、再到下一条指令,这个过程会不断循环,直到程序执行结束,这个不断循环的过程被称为 CPU 的指令周期

a = 1 + 2 执行具体过程如下:

知道了基本的程序执行过程后,接下来用 ​​a = 1 + 2​​ 的作为例子,进一步分析该程序在冯诺伊曼模型的执行过程。

CPU 是不认识 ​​a = 1 + 2​​ 这个字符串,这些字符串只是方便我们程序员认识,要想这段程序能跑起来,还需要把整个程序翻译成汇编语言的程序,这个过程称为编译成汇编代码。

针对汇编代码,我们还需要用汇编器翻译成机器码,这些机器码由 0 和 1 组成的机器语言,这一条条机器码,就是一条条的计算机指令,这个才是 CPU 能够真正认识的东西。

下面来看看 ​​a = 1 + 2​​ 在 32 位 CPU 的执行过程。

程序编译过程中,编译器通过分析代码,发现 1 和 2 是数据,于是程序运行时,内存会有个专门的区域来存放这些数据,这个区域就是「数据段」。如下图,数据 1 和 2 的区域位置:

  • 数据 1 被存放到 0x100 位置;
  • 数据 2 被存放到 0x104 位置;

注意,数据和指令是分开区域存放的,存放指令区域的地方称为「正文段」。

4、程序执行的基本过程_寄存器_08

编译器会把 ​​a = 1 + 2​​ 翻译成 4 条指令,存放到正文段中。如图,这 4 条指令被存放到了 0x200 ~ 0x20c 的区域中:

  • 0x200 的内容是​​load​​ 指令将 0x100 地址中的数据 1 装入到寄存器​​R0​​;
  • 0x204 的内容是​​load​​ 指令将 0x104 地址中的数据 2 装入到寄存器​​R1​​;
  • 0x208 的内容是​​add​​ 指令将寄存器​​R0​​ 和​​R1​​ 的数据相加,并把结果存放到寄存器​​R2​​;
  • 0x20c 的内容是​​store​​ 指令将寄存器​​R2​​ 中的数据存回数据段中的 0x108 地址中,这个地址也就是变量​​a​​ 内存中的地址;

编译完成后,具体执行程序的时候,程序计数器会被设置为 0x200 地址,然后依次执行这 4 条指令。

上面的例子中,由于是在 32 位 CPU 执行的,因此一条指令是占 32 位大小,所以你会发现每条指令间隔 4 个字节。

而数据的大小是根据你在程序中指定的变量类型,比如 ​​int​​ 类型的数据则占 4 个字节,​​char​​ 类型的数据则占 1 个字节。

举报

相关推荐

0 条评论