搞懂程序在CPU的执行过程
高级程序语言和低级程序语言要想在CPU上执行,需要编译成机器码,因此搞懂程序语言在CPU的执行过程其实就是搞懂机器码在CPU的执行过程。
什么是机器码,我在一篇搞懂机器码 的文章里做了介绍,这里不再阐述,有兴趣的同学可以阅读下那篇文章,下面的章节整体采用ARM CPU进行阐述,其他CPU如Inter,AMD过程比较类似。
一.CPU的组成结构
先来了解下CPU的大致结构,如下图
CPU结构图
如上图所示用到了寄存器,控制单元,ALU,MPLX等,下面介绍下CPU的各个组件的功能。
内存地址寄存器(MAR)
保存了当前正在读或者正在写的内存地址
内存数据缓冲寄存器(MBR)
保存了当前刚从内存读出的数据或者准备要写入内存的数据
程序计数器(PC)
保存了下一条要执行的指令的内存地址
指令寄存器(IR)
保存了当前正在执行的指令
通用寄存器
寄存器r1-r8,存储临时的数据例如中间结果)
条件寄存器(CCR)
存储加减法过程中产生的各类标识,比如Z,N,C,V
Z表示当前运算结果为0
N表示当前运算结果为负数
C表示当前运算过程中产生过进位
V表示当前运算结果中产生了溢出
ZNCY例子
逻辑运算单元(ALU)
根据P,Q(MBR),Q(立即数)中存储的值,进行一元或者二元运算,例如加法,减法,逻辑(ADD),逻辑(OR),逻辑(NOT),逻辑异或(XOR)等,并输出运算结果。
控制单元(CU)
解释执行指令寄存器的指令,它利用时钟脉冲信号和操作码生成控制计算机总线,存储器,寄存器等的信号,驱使数据在各个线路进行流动。
多路选择器(MPLX)
多路选择器用来控制写入程序计数器(PC)或者内存地址寄存器(MAR)的数据,根据输入数据,条件码,进行判断,计算出新的地址值后送入达到PC或者MAR
二.机器指令执行过程
CPU执行机器指令分为3个阶段即取指,解码,执行
我们叙述机器码如何在CPU上执行,可以写一段简单的代码,通过这一段代码来解释整个执行过程,复杂的代码原理也是类似,只不过是反反复复地执行相同的操作罢了,下面为一段简单C语言代码
pos1:
int x = 3;
int y = 4;
int z = x + y;
z = z - 7;
if (z == 0)
goto pos2
z=x+2
pos2:
..............
..............'
代码总体意思是x 和 y 相加 减去7,然后判断z的值,如果等于0,则跳转到pos2代码处,否则就继续往下执行
将该代码翻译成ARM CPU 机器码后,列出以下核心的代码
pos1:
ADD r1,[r2],[r3] #将r2,r3寄存器中内存地址对应的数据相加传输给寄存器r1
SUBS r1,r1,#7 #将r1寄存器的内容即(z=x+y)减去7,再存储回r1
BEQ 2013 #如果上一条指令的执行结果为0,则跳转到2013这个地址即pos2
ADD r1,[r2],#2 #将r2寄存器的内容加上2(x+2),再存储回r1寄存器
pos2:
ADD r4,[r5],[r6] #将r5,r6寄存器中内存地址对应的数据相加传输给寄存器r4
该机器码在内存中的分布图如下所示
内存地址 | 存储内容 | 备注 |
1001 | 3 | x |
1005 | 4 | y |
1009 | 0 | z |
1013 | ADD r1,[r2],[r3] | z=x+y |
1017 | SUBS r1,r1,#7 | z=z-7 |
1021 | BEQ 2013 | if(z==0) goto pos3 |
1025 | ADD r1,r2,#2 | z=x+2 |
.................. | .......................................................... | |
2001 | 1 | m |
2005 | 2 | n |
2009 | 0 | h |
2013 | ADD r4,[r5],[r6] | h=m+2 |
首先操作系统将程序和数据加载到内存中,将程序的第一条指令的内存地址,写入到程序计数器(PC),然后CPU就开始不断地执行取值->解码-执行三个操作,直到程序结束。
上述程序,程序计数器存储的第一条指令地址为:1013
2.1 取指
取指的意思就是从内存中获取指令,写入到指令寄存器中,执行过程如下(红色箭头部分)
a.首先从程序计数器(PC)获取指令地址,写入达到内存地址寄存器(MAR)
b.将程序计数器(PC)+4(按照32位系统,一个内存地址占4个字节),从而指向下一个要执行的指令地址。
c.一个时钟周期到来后,根据内存地址寄存器(MAR)中的地址从内存中获取指令,读出指令后存储到内存数据缓冲寄存器(MBR)
d.从内存数据缓冲寄存器(MBR)将指令写入指令寄存器(IR)
2.2 解码
解码过程由控制单元(CU)处理,解码过程比较复杂,不同的指令(操作码不同)解码过程不太一样,我们讲述常用的3类解码方式即操作数地址解码,立即数解码,分支地址解码。
控制单元可以根据指令类型和操作数区分出当前的解码类型,下面表格为内存中的指令和数据。
内存地址 | 存储内容 | 备注 |
1001 | 3 | x |
1005 | 4 | y |
1009 | 0 | z |
1013 | ADD r1,[r2],[r3] | z=x+y |
1017 | SUBS r1,r1,#7 | z=z-7 |
1021 | BEQ 2013 | |
1025 | ADD r1,r2,#2 | z=x+2 |
.................. | .......................................................... | |
2001 | 1 | m |
2005 | 2 | n |
2009 | 0 | h |
2013 | ADD r4,[r5],[r6] | h=m+2 |
经过第一次取指后,当前各个寄存器中的值如下
寄存器类型 | 当前值 |
程序计数器(PC) | 1017 |
内存地址寄存器(MAR) | 1013 |
内存数据缓冲寄存器(MBR) | ADD r1,[r2],[r3] |
指令寄存器(IR) | ADD r1,[r2],[r3] |
r1 | 0 |
r2 | 1001 |
r3 | 1005 |
r4 | 0 |
r5 | 2001 |
r6 | 2005 |
操作数地址解码
操作数地址解码从寄存器中获取内存地址,将内存地址指向内容取出,写回到寄存器中,以ADD r1,[r2],[r3]为例,r2,r3中存储的是操作数的内存地址,解码过程就是需要获取r2,r3内存地址对应的内容,以r2获取操作数的过程为例,r3同r2是相同的过程,如下图
操作数地址解码过程
a.首先将操作数指向的内存地址写入到内存地址寄存器(MAR)
b.一个时钟周期到来后,根据内存地址寄存器(MAR)中的地址,读取数据后,存储到内存数据缓冲寄存器(MBR)
c.将内存数据缓冲寄存器的内容(MBR)写回到通用寄存器r2
ADD r1,[r2],[r3]解码后,当前各个寄存器的值如下
寄存器类型 | 当前值 |
程序计数器(PC) | 1017 |
内存地址寄存器(MAR) | 1005 |
内存数据缓冲寄存器(MBR) | 4 |
指令寄存器(IR) | ADD r1,[r2],[r3] |
r1 | 0 |
r2 | 3 |
r3 | 4 |
r4 | 0 |
r5 | 2001 |
r6 | 2005 |
立即数解码
立即数解码不需要访问内容,它直接可以连接到算数逻辑单元(ALU),从而将立即数写入到ALU(Q(立即数)端口),如指令SUBS r1,r1,#7的解码过程就是将立即数7送到ALU,如下图所示
立即数解码过程
立即数直接被送往了ALU(Q立即数)端口
分支地址解码
分支地址解码的过程是将条件码和操作数(跳转的地址)送往多路选择器的过程,如BEQ 2013 指令,将操作数内存地址2013和条件码送入到多路选择器中,如下图所示
分支地址解码过程
2.3 执行
每个指令解码后,相当于把指令执行需要的数据都准备好了,执行过程就交给运算逻辑单元(ALU)和多路选择器(MPLX)进行处理。
运算逻辑单元(ALU)负责根据准备好的操作数进行运算,将结果进行输出,或者输出到寄存器作为临时结果,或者输出到内存中,以ADD r1,[r2],[r3]为例,它的执行过程将解码后的的操作数,也就是就是将r2和r3寄存器的值,输入到运算逻辑单元的P和Q(MBR)端口,然后通过f(P,Q)执行相加逻辑,输出到寄存器r1中,如下图所示:
运算逻辑单元执行过程
多路选择器负责根据条件码和跳转地址,在其内部进行判断,或者继续顺序执行下一条指令,或者跳转到指定的地址,以BEQ 2013为例,它将根据条件码中Z标识是不是为0,进行判断,如果为0,则跳转到2013,程序计数器的内容就变为了2013,否则继续执行下一条指令,如下图所示
多路选择器执行过程
二.番外篇
上文中已经将运算结果写入到了寄存器,那么怎样写回内存呢,以ARM CPU 为例,通过STR 指令
STR r1, [r2] 该指令将r1寄存器的内容写回到r2指向的内存中(r2是个寄存器,里面的内容是内存地址),如下图
STR指令执行图
a.r2寄存器中的地址写入到内存地址寄存器(MAR)
b.寄存器的数据写入到内存数据缓冲寄存器(MBR)
c.内存数据缓冲寄存器(MBR)写会到内存。
-
机械硬盘作为木桶效应中的短板,在电脑中明显拖了后腿,对于读写速度的发展已经是瓶颈,这也是目前新装机或者升级电脑都会采用固态硬盘一大原因。固态硬盘目前流行且常见的接口分两种,分别SATA接口和M.2接口,两者均可为固态硬盘提供高速读写能力,那么SATA接口和M.2接口的固态硬盘哪个好?下面分享一下SA[详细]
-
在安装好WIN 7系统并使用一段时间后,发现系统盘C盘当时分的容量小了,系统并老是提示系统空间不足,这样的情况,我们可以通过重新分区,或者扩容系统分区来解决!操作过程:1、鼠标右键单击“计算机”图标,从弹出菜单栏选取“管理”项,如图所示: 2、进入计算机管理界面,依次点击“存储——磁盘管理”选项,接[详细]
-
大家在重装系统的需要硬盘分区,磁盘分区是为了方便管理磁盘,每个分区之间相互独立,数据不容易产生混淆,在分区时都会遇到MBR和GPT两种引导模式,应该如何选择了,接下来小编为大家讲解一下。gpt和mbr的主要区别1、分区数量不同1)MBR分区表最多只能支持4个主分区或三个主分区+1个扩展分区(逻辑分区[详细]
-
随着数据时代的爆发,越来越多的个人以及企业用户都需要大容量的存储设备。个人数据珍藏、学校、医院、航空航天数据安全保管等等,可以说数据存储存在于每个角落,未来硬盘容量将会持续增大,而用户对于存储的容量更是不断增强。现在玩游戏的人越来越多,画面变得更加炫酷,同时场景也更接地气,与日常生活的变化如出一辙。[详细]
-
电脑装系统和电脑硬盘分区问题一直是一个热门话题,关于这个话题网上一搜索真是一大堆,但是真正能让人看得懂的没有多少,电脑小白看后还是依然不会,那怎么介绍才能让电脑小白真正明白好懂呢?电脑是由9大硬件组成(台式电脑),组成电脑的8大硬件有:主板、CPU、CPU散热器、内存条、硬盘、显卡、显示器,要是台式[详细]