一文读懂CPU工作原理、程序是如何在单片机内执行的、指令格式之操作码地址码

文章较长,大家可选择性阅读,嘎嘎细

计算机结构

在这里插入图片描述

CPU的运行原理

CPU的控制单元在时序脉冲的作用下,将指令计数器里所指向的指令地址(这个地址是在内存里的)送到地址总线上去,然后CPU将这个地址里的指令读到指令寄存器进行译码。由运算器执行对应的机器指令,并将结果通过地址总线写回数据段

CPU

中间处理器(CPU,Central Processing Unit)是一块超大规模的集成电路,是一台计算机中的控制核心和运算核心。它的主要功能是翻译程序指令和进行数据处理。
中间处理器主要由运算器(算数逻辑运算单元,ALU,Arithmetic Logic Unit)和缓冲存储器(Cache)组成,也包括能实现它们之间联系的数据、控制单元和总线。中间处理器的主要作用是将程序中的指令翻译成机器指令供机器识别,继而实现数据的处理。所以,CPU的根本任务就是执行程序指令。

CPU构成

CPU的根本任务就是执行指令,对计算机来说最终都是一串由“0”和“1”组成的序列。CPU从逻辑上可以划分成3个模块,分别是控制单元、运算单元和存储单元,这三部分由CPU内部总线连接起来。如下所示:

一.控制单元

指令计数器(IC、Instruction Counter)
指令寄存器(IR、Instruction Register)
指令译码器(ID、Instruction Decoder)
操作控制器(OC、Opreater)
1、指令计数器 IC
指令计数器又称程序计数器,是中间处理器内的一个寄存器,其作用是存放当前正在进行的指令的地址。当指令计算器中指令被取出后,计数器内的地址加一或者指针下移一位,此时计数器内的地址即为下一条指令的地址。
2、指令寄存器 IR
指令寄存器的主要功能是存储将要执行的程序指令。由指令计数器中的指令地址找到内存中相对应的指令地址后,处理器将此条指令存储进指令寄存器中,以供后续使用。
3、指令译码器 ID
程序指令存储进处理器的指令寄存器后,由指令译码器将由高级语言表示的指令翻译成计算机能够识别的机器语言。
4、操作控制器
操作控制器的功能就是根据指令操作码和时序信号,产生各种操作控制信号,发送给运算单元,完成取指令和执行操作的控制。

二、运算单元

计算机的运算包括算术运算(如加减乘除)和逻辑运算。 处理器内的运算单元接收控制单元发出的信号和存储单元内的对应数据,实现操作的执行。
故,运算单元是中间控制器内的执行单元,它的所有动作都按照控制单元发出的信号进行。

三、存储单元

CPU的存储单元主要由CPU的内缓存寄存器和寄存器组构成,主要用于暂时存放数据(包括待处理的和已处理的数据)。
由于CPU访问自身内寄存器的访问速度比CPU访问系统内存数据的访问速度快得多,所以,将内存中的数据读取进CPU的内缓存器中,减少了CPU访问系统内存的次数,提 高了访问效率和CPU的工作速度。
在这里插入图片描述

总结CPU的运行原理:

CPU的控制单元在时序脉冲的作用下,将指令计数器里所指向的指令地址(这个地址是在内存里的)送到地址总线上去,然后CPU将这个地址里的指令读到指令寄存器进行译码。由运算器执行对应的机器指令,并将结果通过地址总线写回数据段

具体如下:

1、(读)取指令:CPU的控制器从内存读取一条指令并放入指令寄存器。指令的格式一般是这个样子滴:
在这里插入图片描述
操作码就是汇编语言里的mov,add,jmp等符号码;操作数地址说明该指令需要的操作数所在的地方,是在内存里还是在CPU的内部寄存器里。
2、译码指令(解码):指令寄存器中的指令经过译码,决定该指令应进行何种操作(就是指令里的操作码)、操作数在哪里(操作数的地址)。
3、 执行指令,分两个阶段“取操作数”和“进行运算”。
4、 修改指令计数器,决定下一条指令的地址。

下面四张图综合四个人讲解CPU工作原理,供参考

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

指令执行:

下面文章来源:
https://blog.csdn.net/MiracleWW/article/details/114711039
(https://blog.csdn.net/MiracleWW/article/details/114711039)

程序是指令的有序集合,程序按照顺序执行

那么什么是指令:

机器指令的二进制表示方式,是指令在程序存储器中存放形式,是CPU可直接读取、识别并执行的唯一形式。程序代码的本质就是一条一条的指令,我们需要通过编码的方式让CPU知道我们需要它干什么,最后由译码器翻译成一条条的机器指令。机器指令主要有两部分组成:
在这里插入图片描述
操作码:表征指令的操作特性与功能 (指令的唯一标识) 不同的指令操作码不能相同,每一种编码代表一种指令;操作码是指令的一部分,它告诉处理器应该要做什么。它包含表示 CPU 要执行的实际操作的说明。操作码类似汇编语言里的mov,add,jmp等符号码,在单片机内都是机器语言,二进制数。组成操作码字段的位数一般取决于计算机指令系统的规模。例如,一个指令系统只有8条指令,则有3位操作码就够;如果有32条指令,那么就需要5位操作码。
二、操作码分类
操作码可以分为固定长度的代码和可变长度的代码

1、固定长度的代码
所有指令操作码的长度相等
例如:某计算机共有64条指令,采用固定长度操作码,需要6位编码,从000000~111111 2的6次方为64
优点:编码方法简单,便于指令的译码
缺点:不方便指令系统中增加新的指令(扩展不方便)

2、可变长度的代码
不等长的指令操作码可以减小操作码的平均长度,提高指令编码的效率,从指令的扩展性来看,也希望操作码长度可变。
这是操作码不固定的指令格式,四位是基本的操作码,还可以扩充,但是指令的字数不变,就是说把不用的地址码部分可以做操作码用。
例如:假设某机器的指令长度为16位,包括4位基本操作码和三个4位地址码段。
①表示三地址指令:因有4位操作码则能表示16条;②表示二地址指令:因有8位操作码则可表示256条;③表示一地址指令:因有12位操作码则可表示4096条
如果需要三地址、二地址、一地址指令各15条、零地址指令16条,则一样能够采用可变格式操作码实现。例如可以这样规定:
15条三地址指令的操作码为:0000 ~ 1110 (操作码4位可表示16条指令,由于只有15条,所以还剩余一种状态1111,可以做二地址指令的标记)
15条二地址指令的操作码为:前4位1111, 即 1111 0000 ~ 1111 1110
15条一地址指令的操作码为:前8位均为1, 即 11111111 0000 ~11111111 1110
16条零地址指令的操作码为:前12位均为1, 即 1111111111110000~1111111111111111

我当时看的时候也想问为什么 不过最后我知道了不是一定要 多少条的,是为了方便 才 15条的。(操作码4位可表示16条指令,由于只有15条,所以还剩余一种状态1111,可以做二地址指令的标记)

例如:设某台计算机有100条指令,要求:

采用固定长度操作码编码,请设计其操作码编码
假设这100条指令中有10条指令的使用改了达到90%。其余90条指令的使用概率达到10%.
请采用不定长编码设计一种操作码编码的方案,并求出操作码的平均长度(常用指令用短编码 不常用指令用长编码)

答、1)采用固定长度操作码编码,需要7位操作码,取其中100个代码作为操作码 0000000~1100011之间的代码代表100条指令(长度为7)
其余的1100100~1111111共28个代码可用于增加新的操作码

2)采用不固定长度的操作码编码,可以用4位代码对10条指令进行编码,用8位代码对90条指令进行编码。00001001对应10条常用的指令,从未使用的10101111的代码后面扩展4位

10100000~10101111     1610110000~10111111     1611000000~11001111     1611010000~11011111     1611100000~11101111     1611110000~11111001     10

已上的1010 ,0000~1111,1001之间的90个代码表示其余90条指令
指令操作码的平均长度为:

4*90%+8*10%=4.4  小于等长编码的7位

地址码
地址码直接给出操作数操作数的地址(操作数地址说明该指令需要的操作数所在的地方,是在内存里还是在CPU的内部寄存器里,地址码中可以包含存储器地址。也可包含寄存器编号。)
指令中可以有一个、两个或者三个操作数,也可没有操作数,根据一条指令有几个操作数地址,可将指令分为零地址指令。一地址指令、二地址指令、三地址指令。4个地址码的指令很少被使用。

操作码字段	  地址码
操作码	  A1	A2	A3	  三指令地址
操作码	  A1	A2	      二指令地址
操作码	  A1	          一指令地址
操作码	 	              零指令地址
  • 零地址指令在机器指令中没有地址码,用来进行空操作、停机操作、中断返回操作等。
  • 一地址指令:指令编码中只有一个地址码,指出了参加操作的一个操作数的存储位置,如果还有另一个操作数则隐含在累加器中
eg: INC AL 
    INC [S1]

二地址指令:指令编码中有两个地址,分别指出了参加操作的两个操作数的存储位置,结果存储在其中一个地址中

(op a1,a2:a1 op a2 a1)
eg:  MOV  AL,BL
     ADD  AL,30

三地址指令:指令编码中有3个地址码,指出了参加操作的两个操作数的存储位置和一个结果的地址

(op a1,a2,a3: a1 op a2  a3)

二地址指令格式中,从操作数的物理位置来说有可归为三种类型

寄存器-寄存器(RR)型指令:需要多个通用寄存器或个别专用寄存器,从寄存器中取操作数,把操作结果放入另一个寄存器,机器执行寄存器-寄存器型的指令非常快,不需要访存。

寄存器-存储器(RS)型指令:执行此类指令时,既要访问内存单元,又要访问寄存器。

存储器-存储器(SS)型指令:操作时都是涉及内存单元,参与操作的数都是放在内存里,从内存某单元中取操作数,操作结果存放至内存另一单元中,因此机器执行指令需要多次访问内存。
在这里插入图片描述

实例

在这里插入图片描述
在这里插入图片描述
上例程序的执行过程描述如下:
PC中的初始地址值为2000H
(1) CPU取出2000H单元中指令首字节(操作码)E5H, PC+1=2001H,译:本指令尚有第二字节直接地址
(2) CPU取出2001H单元中操作数3AH,PC+1=2002H,执行:将3AH中数送入A。
(3) CPU取出2002H单元中指令操作码85H,PC+1=2003H,译:尚有二字节地址码
(4) CPU取出2003H单元中地址码3BH,PC+1=2004H,取出3BH单元中的数
(5) CPU取出2004H单元中地址码3AH,PC+1=2005H,执行:将数送入3AH单元
(6) CPU取出2005H单元中指令操作码F5H,PC+1=2006H,译:尚有一字节地址码
(7) CPU取出2006H单元中地址码3BH,PC+1=2007H,执行:将A中数据送入3BH单元
(8) CPU取出2007H单元指令操作码02H,PC+1=2008H,译:尚有二字节目标地址
(9) CPU取出2008H单元中地址高字节20H,PC+1=2009H,尚有一字节地址码
(10) CPU取出2009H单元中地址低字节07H,PC+1=200AH,执行:2007H PC
转步骤(8)无限循环
补充:

PC(程序计数器,程序指针)的作用:
PC:始终存放着CPU要取出执行的下一个机器指令代码的存放单元的地址。
或:始终指向要取出执行的下一条指令代码存放单元,
∵51单片机程序存储器空间为64KB,使用16bit地址码
∴51单片机的PC为16bit(双字节)
PC的作用:
● 51单片机复位后,初始化PC=0000H,∴51单片机总是以0000H地址开始执行程序的。51单片机程序存储器空间中,0000H地址处一定要有存储器并存放有效的程序指令。
● CPU总是以PC中的内容为地址从程序存储器中取指令代码的。
● CPU每取出一个字节的指令代码自动地将PC加1(PC←PC+1)实现程序的顺序执行逻辑。
● CPU执行跳转指令功能时为将指令指定的跳转目标地址置入PC(使下一次取的是该地址处的指令)实现了程序跳转执行逻辑。

图1为程序计数器的示意图。图中,假定(1)执行地址1000h中的指令,(2)执行地址1000h中的指令后,程序计数器的値自动增加一个量并显示出下一个地址1001h,接下来,(3)CPU执行地址1001h中的指令。
在这里插入图片描述

那么一条简单的指令执行,涉及到了那些组件?

控制器(CU)和运算器(ALU)
PC寄存器(程序计数器):用于存放下一条需要执行的指令地址信息,注意是下一条指令的地址!

指令寄存器:用于存放当前正在执行的指令,注意是当前的指令!

指令译码器:用于翻译指令信息,与指令寄存器相连
在这里插入图片描述
那么一条指令的执行就应该包含
在这里插入图片描述
在这里插入图片描述
1.取指令:CU根据PC寄存器中的指令地址,去内存或者指令缓存中获取具体的指令,并加载到指令寄存器中。即完成了“取指令”操作。与此同时,指令计数器的地址变成下一条指令的地址。
2.分析指令:从内存中取出的指令不能被计算机直接识别。通过指令译码器的处理,寄存在指令寄存器中的指令变成能够被计算机直接识别的机器语言以实现指令的执行。拿到指令之后,指令译码器将指令寄存器中的指令进行翻译,向ALU发起控制信号和指令信息。此时PC寄存器自增即+1,加载下一个要执行的指令地址(至少此时是这样的,此为顺序寻址)。
3.执行指令操作控制器将译码后的指令发送给相应的运算单元,运算单元结合存储单元内的数据,对数据进行进行相应的操作。ALU拿到相关信息之后进行相关的计算。
4.访问内存(或缓存):如果涉及到相关数据需要去缓存中拿,那就去取数据。
5.数据写回:将计算结果写入到寄存器中,写入到缓存中,甚至写入到内存中。
在这里插入图片描述

代码是如何在单片机上运行起来的?

此部分引用文章,如有侵权请联系作者删除
原文链接:https://blog.csdn.net/yechongbinbin/article/details/115146615
在这里插入图片描述
代码在单片机上跑起来,一般有6个步骤:

  • 1.写好源文件。

  • 2.准备好启动文件(一般半导体厂商提供,也可以自己根据需求进行裁剪编写)。这个文件直接是用汇编写的,主要完成三个工作:初始化堆栈,定义中断向量表,进行复位中断(初始化寄存器、时钟和跳转到main函数)。
    (1)初始化堆栈:主要定义栈、堆地址、大小和一些格式
    在这里插入图片描述
    (2)定义中断向量表:可以简单理解为各个小函数的地址。要放在Flash的0位置处。例如要运行Reset_Handler这个中断处理函数,PC就会先先访问这个中断向量表,得知Reset_Handler在哪个地址,然后PC跳到相应的位置开始执行Reset_Handler, 里面定义了各种中断发生后CPU要做的事。
    在这里插入图片描述
    (3)进行复位中断:单片机一上电复位或者按下复位按钮执行的初始化操作。首先进行系统初始化,然后会跳转到我们写的应用程序main函数。
    在这里插入图片描述

  • 3.编译生成二进制机器码。把写的代码变成机器可以认识的二进制文件。一般用集成好的开发环境如MDK,包括了预处理、编译、链接、加上地址头等等,最终生成特定MCU的二进制文件。

  • 4.烧写单片机的FLASH。将第三步生成的二进制文件通过烧录器、仿真器等媒介烧录进FALSH。当然不一定是FLASH,还可以是其他存储芯片。

  • 5.复位。烧录完复位一下。让芯片里的各个寄存器恢复到初始状态,主要让CPU的PC寄存器恢复到0,重头开始跑复位中断处理。

  • 6.运行用户代码。复位后跳转到main函数执行。

看到这里你肯定会想,并不是所有的指令都是顺序执行的,比如if····else,比如方法调用,此时PC寄存器也是自增加1嘛?我们来讲讲if····else和方法调用。
先来看if····else,下边有一小块代码

int r = 1;
int a = 10;
  if (r == 0)
  {
    a = 1;
  } else {
    a = 2;
  } 

很简单的一个if判断以C语言为例 if部分翻译为汇编代码就是

if (r == 0)
  3b:   83 7d fc 00             cmp    DWORD PTR [rbp-0x4],0x0
  3f:   75 09                   jne    4a <main+0x4a>
    {
        a = 1;
  41:   c7 45 f8 01 00 00 00    mov    DWORD PTR [rbp-0x8],0x1
  48:   eb 07                   jmp    51 <main+0x51>
    }
    else
    {
        a = 2;
  4a:   c7 45 f8 02 00 00 00    mov    DWORD PTR [rbp-0x8],0x2
  51:   b8 00 00 00 00          mov    eax,0x0
    } 

可以看到,这里对于 r == 0 的条件判断,被编译成了 cmp 和 jne 这两条指令。
这两条指令中cmp表示比较的意思,这明显是一条二地址指令,cmp是操作码,后边两个是地址码,意思就是将rbp寄存器中偏移量为4的位置的数取32位(DWORD PTR)出来,和0(0x0)比较,并将比较结果存到条件码寄存器中。
跟着的 jne 指令,是 jump if not equal 的意思,它会查看对应的零标志位。如果为 0,会跳转到后面跟着的操作数 4a 的位置。这个 4a,对应这里汇编代码的行号,也就是上面设置的 else 条件里的第一条指令。当跳转发生的时候,PC 寄存器就不再是自增变成下一条指令的地址,而是被直接设置成这里的 4a 这个地址。

那么CPU 再把 4a 地址里的指令加载到指令寄存器中来执行。mov 指令把 2 设置到对应的寄存器里去,相当于一个赋值操作。然后,PC 寄存器里的值继续自增,执行下一条 mov 指令。
最后一条mov指令的第一个操作数 eax,代表累加寄存器,第二个操作数 0x0 则是 16 进制的 0 的表示。这条指令其实没有实际的作用,代表我执行完了,给 main 函数生成了一个默认的为 0 的返回值到累加器里面。
然后是if条件之后我们注意到有个jmp指令,它之前的mov指令和4a是一样的意思,jmp指令,也就是jump的缩写,这是一个无条件跳转指令。跳转的地址就是这一行的地址 51,也就是说这个指令同样会改变PC寄存器中的地址信息,即将PC寄存器中的值设置为51(51大家都能使用,没必要生成两条指令)。具体流程如图所示,for循环也是同样的道理,不过涉及到具体的指令意义需要大家自己探索,但是流程是一样的,都是通过指令改变PC寄存器中的指令地址,引导CPU执行自己想要执行的指令。
在这里插入图片描述

  • 8
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
在现代嵌入式开发领域,通过了解客户需求和电子产品趋势,搜集市面上大量的不同型号的MCU资料,结合市场上刚出现的低成本高性能MCU新产品,是成功进行MCU选型的基础。一般来说,嵌入式系统开发人员在选择MCU时,通常遵循四项主要标准∶功能、可用性、成本和熟悉程度。   微控制器(Microcontroller;MCU)是一种无所不在的嵌入式控制晶片,玩具、家电、医疗、汽车等领域都有其存在,负责各种感测、监控工作,例如我们常见的电饭煲、电磁炉、咖啡壶等内部均由MCU负责感测水温,并接受使用者的指示是否该加温、沸腾,同样的冷气机的温控也是用MCU来实现。此外,如桌上电脑所用的键盘、滑鼠等也各有一颗MCU,负责将敲打的键码、指标的X/Y轴位移偏量等资讯回传给电脑CPU。   对於选择MCU进行设计的系统设计师来说,可获得的大量的不同型号MCU会让选型工作变得复杂,如SiliconLabs工作电压低至0.9V的8位元MCU,德州仪器针对低功耗应用的多款16位元MSP430,飞思卡尔和英飞针对汽车应用的MCU方案,Atmel的AVR系列和Microchip的PIC系列一直在推陈出新……虽然新的32位ARM核Cortex-m3处理器已经发布许久,古老的8位8051核还是在不同MCU中占领主流地位……面对缤纷多彩的MCU世界,正确把握MCU发展趋势,熟悉MCU架构,甚至於借助选择工具进行分析比较就显得极其必要。   MCU的主要分类:   按用途分类:   通用型:将可开发的资源(ROM、RAM、I/O、EPROM)等全部提供给用户。 专用型:其硬件及指令是按照某种特定用途而设计,例如录音机机芯控制器、打印机控制器、电机控制器等。 按其基本操作处理的数据位数分类:   根据总线或数据暂存器的宽度,单片机又分为1位、4位、8位、16位、32位甚至64位单片机。   4位MCU大部份应用在计算器、车用仪表、车用防盗装置、呼叫器、无线电话、CD播放器、LCD驱动控制器、LCD游戏机、儿童玩具、磅秤、充电器、胎压计、温湿度计、遥控器及傻瓜相机等;8位MCU大部份应用在电表、马达控制器、电动玩具机、变频式冷气机、呼叫器、传真机、来电辨识器(CallerID)、电话录音机、CRT显示器、键盘及USB等;8位、16位单片机主要用于一般的控制领域,一般不使用操作系统,16位MCU大部份应用在行动电话、数字相机及摄录放影机等;32位MCU大部份应用在Modem、GPS、PDA、HPC、STB、Hub、Bridge、Router、工作站、ISDN电话、激光打印机与彩色传真机;32位用于网络操作、多媒体处理等复杂处理的场合,一般要使用嵌入式操作系统。64位MCU大部份应用在高阶工作站、多媒体互动系统、高级电视游乐器(如SEGA的Dreamcast及Nintendo的GameBoy)及高级终端机等。   8位MCU工作频率在16~50MHz之间,强调简单效能、低成本应用,在目前MCU市场总值仍有一定地位,而不少MCU业者也持续为8bitMCU开发频率调节的节能设计,以因应绿色时代的产品开发需求。   16位MCU,则以16位运算、16/24位寻址能力及频率在24~100MHz为主流规格,部分16bitMCU额外提供32位加/减/乘/除的特殊指令。由于32bitMCU出现并持续降价及8bitMCU简单耐用又便宜的低价优势下,夹在中间的16bitMCU市场不断被挤压,成为出货比例中最低的产品。   32位MCU可说是MCU市场主流,单颗报价在1.5~4美元之间,工作频率大多在100~350MHz之间,执行效能更佳,应用类型也相当多元。但32位MCU会因为操作数与内存长度的增加,相同功能的程序代码长度较8/16bitMCU增加30~40%,这导致内嵌OTP/FlashROM内存容量不能太小,而芯片对外脚位数量暴增,进一步局限32bitMCU的成本缩减能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不熬夜,早点睡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值