组合电路和时序电路是计算机原理的基础课,组合电路描述的是单一的函数功能,函数输出只与当前的函数输入相关;时序电路则引入了时间维度,时序电路在通电的情况下,能够保持状态,电路的输出不仅与当前的输入有关,而且与前一时刻的电路状态相关,如我们个人PC中的内存和CPU中的寄存器,均为时序电路。
说了这么多,我们学习的组合电路和时序电路在计算机中又是怎么一回事呢?为了便于理解,下面以一个大家都能接受的C语言程序开始,从上层向下层开始解释。
void main(){
int a = 3, b = 5;
int sum = a + b;
}
这个例子大家都能明白,main函数要做的事情就是实现两个数的加法操作。这是我们人类的思维方式,但是计算机并不认识,如何让计算机理解呢?于是,我们需要将上面这个程序翻译成机器能理解的模样,这时候就需要借助编译器(如常见的gcc、msc等)将上面的程序翻译成MIPS指令(不同的CPU有不同的指令集,包括X86指令集、MIPS指令集、Sparc指令集等,我们在这里用MIPS指令集,咱们的龙芯也是采用MIPS指令集),如下所示:
#下面的每条汇编代码对应一个二进制
addi $t0, 0, 3 # a = 0+3, a保存在$t0寄存器中, 对应的二进制代码为:0010 00** **** **** **** **** **** ****(这里的星号*表示二进制,这里暂时不关心)
addi $t1, 0, 5 # b = 0+5, b保存在$t1寄存器中
addi $t2, $t1, $t0 # sum = a + b, sum保存在$t2寄存器中
到这里,大家一定还在疑惑,不是说要翻译成二进制代码吗?怎么是MIPS汇编语言?对,就是汇编语言,这个汇编语言中的每一条指令就对应一条二进制代码,汇编的方式更容易让人理解。
现在我们得到了计算机可以理解的MIPS指令(可以想象成可执行程序)了,接下来的问题是如何执行MIPS指令。
要执行程序,首先必须将可执行程序文件(从外设)加载到内存。可执行文件加载到内存时,操作系统会为每个可执行程序在内存中分配四个区:
1 代码区。也就是前面的到的汇编代码所对应的二进制码
2 全局数据区。全局变量,静态变量放在这个区
3 堆区。表示在程序执行过程中,动态申请的空间在这个区,如C语言中的malloc, free操作均是针对此区中的对象执行申请或释放操作
4 栈区。函数运行时,局部变量的保存区域。
我们重点关注代码区和栈区,初始时,其分布如下图所示:
代码区-1.png
其中PC(Program Counter)是程序计数器(是CPU中的一个寄存器,具有数据存储功能),即用来指示下一个即将执行的指令的地址,本例中,进入main函数后,即将执行的第一条指令是a = 3,其地址为:0X FF FF FF 00, 因此PC指向其对应的汇编代码的地址。
CPU根据PC的的值,从指定地址0X FF FF FF 00处获取指令,然后解析指令,并执行指令(即执行a=3)。
当a = 0执行完毕后,PC执行操作:PC = PC + 4,PC指向0X FF FF FF 04,即b = 5的指令的地址。此时,栈区的状态为:
栈区-1.png
接着,CPU根据PC的的值,从指定地址0X FF FF FF 04处获取指令,然后解析指令,并执行指令(即执行b=5)。当b=5执行完毕后,PC执行操作:PC = PC + 4,PC指向0X FF FF FF 08,即sum=a+b的指令的地址。此时,栈区的状态为:
栈区-2.png
然后,CPU根据PC的的值,从指定地址0X FF FF FF 08处获取指令,然后解析指令,并执行指令(即执行sum=a+b)。当sum=a+b执行完毕后,PC执行操作:PC = PC + 4,PC指向0X FF FF FF 12(因为,指令已经执行完毕,这里应该提示要从main函数返回)。此时,栈区的状态为:
栈区-3.png
至此为止,main函数内部的流程基本上陈述完了(关于函数间调用,相对复杂,计算机组成中会详细讲解),但如何实现这些步骤呢,其中的关键问题包括如下:
问题:
1、知道内存地址,如何定位到那个地址???答案:地址译码器
2、获取到a=3对应的指令后,如何知道是做a=0+3的操作???答案:解析指令,指令译码器
3、PC寄存器如何保存值?如何做加4操作?答案:计数器(寄存器讲解)
-
计算机
+关注
关注
19文章
7488浏览量
87850 -
时序电路
+关注
关注
1文章
114浏览量
21696 -
组合电路
+关注
关注
0文章
11浏览量
6691
发布评论请先 登录
相关推荐
评论