0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

cpu的程序是如何运行起来的

工程师 来源:羽林君 作者:羽林君 2020-09-11 09:26 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

作者:良知犹存

转自:羽林君

1

CPU的硬件最小原子

计算机从上世纪四十年代发展到现在有八十多年了,我们现在开发应用以及很少会涉及到底层的部分,硬件设计的电子专业在学校里面会学习模电数电这两门课,今天的第一部分就从这里说起。

一般我们不考虑物理的硬件底层的实现逻辑,但是为了后续的机器码的介绍,这里开始介绍CPU的基本组成部分。

我们都知道现在的CPU是无数的晶体管组成,一块很小的CPU用显微镜观察可以看到上百万个元器件,那么最早电脑是啥样的呢?感谢Crash Course Computer Science的视频,下面有很好照片都是从她的视频中截取。以及感谢《CODE》,好多资料也是从此书得来。

最早的计算机,它有76万5千个组件,300多万个连接点和大约804公里长的用线,这个是真的大,而且它的核心控制还是用继电器实现控制逻辑的。

此外,它的性能相较于于现在的电脑来说简直微不足道。

好了言归正传,我们直接介绍现在计算机中的CPU组成,之前用继电器、电子管进行控制计算,这些基本的元器件使得计算机体型庞大,后来半导体的出现,使得计算机的体积大大减小。没有使用半导体的时候,科学家使用继电器等进行控制电路的开关,控制电路电流的高和低,通过布尔代数组合形成我们现在经常说的逻辑门,继而实现数据的控制。

如上图所以它会出现如下情况

这其实就是一个简单开关的与门(AND)电路,所有的变量输入是1的时候,输出才为1。相应的还有非门、或门、异或门等。

那么半导体是如何做到的呢?下面所示是三极管变化而成的与门(AND)电路,通过两个三极管连接(三极管的工作原理可以百度一哈),实现逻辑。

这是非门(NOT),输入1输出位0,输入位、为0输出为1.

这是或门(OR),只有A、B两个同时输入0的时候,输出才为0,其余都为1.

这是常用的逻辑门的图形表示以及真值表显示,最后一栏为真值表显示,其中A、B为输入,F为输出。

基于这些逻辑的组合我们可以变成最小的11位二进制逻辑的加法器,1bit的数据锁存器,再扩展为8位加法器,256M存储器。

2

CPU的模块组成过程

讲完了CPU组成的最小原子结构,接下来我们抽象出来了逻辑门进行

首先我们先介绍一下CPU的基本架构

一块完整可以执行程序CPU功能部件,里面有基本的ALU算数逻辑单元、控制单元、外部储存器(储存数据和程序)。

1970年发布的时候,它是第一个封装在单个芯片内完整的ALU。

ALU(算数逻辑单元)有两个单元:一个算数单元(加法器),负责计算机里的所有数字操作,例如加减法、增量运算等;一个逻辑单元,负责一些简单的数值测试,例如检测ALU输出是否为零的的电路

加法器:

用单个晶体管一个个去拼,把这个电路做出来,到那时会很复杂很难理解。所以我们更高层面的抽象-逻辑门去实现(AND、OR、NOT、XOR)。

下面这是一个1位的加法器:

二进制数的“和”可以由异或门得到,而“进位”可以由与门得到,所以可以把异或门和与门结合起来来完成两个二进制数 A和B的加法

AB只能输入0或者1,也就是这个加法器能算0+0,1+0或者1+1。

脱离具体的形状,我们可以把以上的一个加法器,抽象为一个符号用来显示:

然后我们在进行扩展,把八个全加器连接,这样就变成了一个8bit的加法器。每个全加器的进位输出都是下一个全加器的进位输入:

用一个抽象的框图进行表示,其中输入是A和B标识为从A0~A7及B0~B7。输出为和输出,标识为从 S0~S7:

这样我们就构造了一个简单8位的加法器。

逻辑单元:同样AND、OR、NOT、XOR的执行,如下图一个简单的判断输出是否为0的电路

它用一堆OR门检查其中一位是否为1,哪怕只有一个输入的bit(位)为1,但都会被被或门到最后一个NOT(非)门进行取反,所以只有输入的数字是0,输出才能是为1。

告诉ALU执行加减法,下面图片里面的的V代表ALU部分。

通过ALU的FLAGS进行判断,下面有三个标志一个是OVERFLOW(操作超出了总线宽度,设置为true(1))、ZERO(运算结果是否为零)、NEGATIVE(运算结果第一位为1,则设置为true(1),表示为负数)

这就是ALU中的一些单元,其实也是一大堆逻辑门巧妙连到一起。

此外我们还需要存储器(memory),如果ALU计算出来数据丢掉那么数据也没什么用了,所以需要内存把数据保存起来,与ALU一起组成CPU

之前的介绍都是单向顺序执行的电路,那有什么可以返回的电路呢,通过输出来控制影响输入。

进行AND 、NOT、OR组合,变成一个1位锁存器

输入STE为1,输出为1

输入RESTE为1,输出为0

如果设置和置位都为0,电路会输出最后放置的状态,所以它就保存住1bit位的数据

其中这样一个1位的锁存器,放入的动作叫做写,拿出数据的动作叫做读

为了好显示,我们使用再高一级别的抽象层,用下面的框图表示:

随着芯片锁存器大小的扩展,正常连接需要的线是非常之多,所以引入了矩阵方式:

为了将地址转化成为行和列 还要用多路复用器,这就是一个基本的SDRAM的组成结构。

SRAM DRAM FLASH NVRAM,大家功能上相似,但是用不同的电路储存单个bit的数据,比如使用不同的逻辑门、电容器、、电荷捕获或者忆阻器。但是根本上,这些技术都是矩阵层层嵌套,来储存大量的信息。

3

CPU的代码语言执行以及编程语言的变化过程

通过不同的逻辑门,我们逐渐搭建起了CPU的硬件部分,同时也抽象到了高层次的“微体系架构”,我们开始告诉CPU的模块进行操作,CPU里面都是101二进制数据,那怎么和CPU执行指令挂上钩呢?

最早执行机器使用就是穿孔卡片,通过穿孔卡片的特殊位置有没有穿孔,决定机器执行的不同步骤。

在计算机早期,程序员编程必须用机器码写程序,一般会在会在纸上写一个“高层次”的描述——伪代码,例如:从内存中获取当月销售额,再计算出税费。

这里展示一个简单范例代码,一段机器码 00101110。

首先这个机器码分为前四位和后四位,前四位代表操作码,后四位代表地址。

首先在指令表可以查到 0010 对应着执行指令是LOAD_A 意思为从内存地址取出数据,放到寄存器A中。

CPU看到00101110是怎么执行的呢?

首先CPU有两个执行时候的寄存器:

指令地址寄存器,一个追踪器,负责追踪程序运行到哪里了;

指令寄存器,负责储存当前指令

其次,CPU执行指令有三个阶段: 取指令-》解码-》执行

取指令:负责把指令从RAM中复制到指令寄存器中

如下所示:CPU把0010 1110放到指令寄存器中

解码阶段:负责解析复制过来的指令对应到操作码是哪个执行,先解析0010

LOAD_A指令的工作:把RAM里面的值放入寄存器A中

再解析后四位1110,为地址14

接下来通过控制单元进行选择确认是否执行load指令

当然控制单元也是由逻辑门连接起来的,这个时候需要一个电路,检查操作码是不是LOAD_A对应的0010

执行阶段:当确认了执行的操作码,我们就开始执行

从地址1110(10进制14)读取出0000 0011的数据,因为是LOAD_A指令,我们把该数据放进寄存器A,不操作其他寄存器

本次执行完成,然后我们就把“指令地址寄存器”+1,执行下一条命令,一直重复到代码结束。

如果我们遇到了例如加减运算时候,就可以用到ALU了,数据寄存器把需要进行add的两个数据输入,然后在发送操作码给ALU,ALU开始执行最后输出到暂存的寄存器,关闭ALU,最后再把数据放入正确的寄存器

除了执行动作,现代CPU还有时钟控制。很早的计算机都是用人工插拔来进行每一条指令的计算,但是对于现在的CPU执行频率来说,人工是做不到这样的速度,所以现在CPU里面有专门的时钟进行管理CPU的节奏,来告诉CPU要取指令-解码-执行。类似于练习乐器时候使用的节拍器一样。

前面介绍程序运行时候我们是假设程序已经在内存里面了,但实际上程序储存的位置不在内存,并且需要在执行时候加载到内存里面。只要内存足够,不仅可以储存要运行的程序,还可以存程序需要的数据,以及运行程序时候产生的新数据。

不过早期编程都是专家活,不管是全职还是技术控,都需要非常了解底层硬件,要懂操作码、寄存器等才能写程序,所以编程很麻烦,哪怕是工程师和科学家都无法完全发挥计算机的能力

所以程序员开发出了一种新语言,更高层次,更可读性,每个操作码分配一个简单的名字——助记符。助记符后面紧跟数据,形成完整的指令。这样程序员就不用0和1去写代码,可以用load jump等助记符开始编程,这就是汇编。前面我们讲过这些助记符,应该还是比较容易理解的。但是CPU是只能识别二进制的,所以程序员又写了二进制程序来帮忙,它可以读懂文字指令,自动转化成二进制指令,这个程序就叫做——汇编器。

汇编器读取用汇编语言写的程序,然后转成机器码。LOAD_A 14 是一个典型的汇编代码。

发展到现在,就英特尔的CPU 酷睿i7有上千种指令和指令变种,长度从一个字节到15个字节。

FORTRAN,是IBM1957年发布的语言,而主持FORTRAN的项目的总监John Backus说,他只是因为懒,所以就开发了新的语言,是的大部分新程序的开发是因为更高效率的开发,把一个月的开发时间编程一周,在变成一天。

就FORTRAN使用效果来说,确实也达到了,平均FORTRAN写的程序要比同等的汇编写的代码少二十倍。然后FORTRAN编译器会把FORTRAN代码转为机器码。

然后陆续新的语言不断产生,60年代有ALGOL、LISP和BASIC等语言;70年代有Pascal、C和Smalltalk;80年代有C++、Objectivs-C和Perl;90年代有Python、Ruby和Java;2000开始出现Swift、C#、Go。未来语言还会越来越多,新的语言用新的平台和新的技术,让我们可以快速的开发使用。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 电路
    +关注

    关注

    173

    文章

    6093

    浏览量

    179133
  • cpu
    cpu
    +关注

    关注

    68

    文章

    11370

    浏览量

    226391
  • 程序
    +关注

    关注

    117

    文章

    3849

    浏览量

    85577
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    TMS320F28xxx DSP:从内部闪存运行应用程序的全面指南

    TMS320F28xxx DSP:从内部闪存运行应用程序的全面指南 在嵌入式系统设计中,让应用程序在TMS320F28xxx DSP的内部闪存上运行是一个常见需求。本文将深入探讨从内部
    的头像 发表于 04-23 13:40 234次阅读

    S32M276官方程序无法运行,请问这是怎么回事,要怎样解决?

    在使用官网的电机例程NXPMC_DevKits S32M276SFFRsw S32M276SFFRD_PMSM_FOC_1Sh 程序时; 运行程序报错如下: 启动目标 CPU...
    发表于 03-31 06:26

    在睿思芯科灵羽RISC-V服务器CPU实现多实例OpenClaw并发运行

    睿思芯科基于自研“灵羽“系列服务器CPU实测单板承载多实例OpenClaw并发运行。基于标准Linux+Docker环境并行响应不同业务需求,为企业未来的大规模Al Agent托管打开了更优单位算力成本的新路
    的头像 发表于 02-11 09:37 774次阅读
    在睿思芯科灵羽RISC-V服务器<b class='flag-5'>CPU</b>实现多实例OpenClaw并发<b class='flag-5'>运行</b>

    MangoTree新品剧透:全新PXI形态+最强CPU #PXI #PXIe #测控 #CPU

    cpu
    芒果树数字
    发布于 :2026年01月30日 11:36:11

    单片机里的程序运行方式

    我们想要理解单片机是如何运行程序的,我们首先需要了解单片机的组成,我们这里以80C51单片机为例来理解程序在单片机中是如何运行的。 单片机的组成8051单片机的内部硬件结构包括: 中央处理器
    发表于 01-16 06:57

    Linux 下交叉编译实战:跑起来你的第一个 STM32 程序

    起来你的第一个STM32程序。一、准备工作在开始之前,需要准备:1、Linux开发环境Ubuntu、Debian或其他主流发行版都可以。2、ARMGCC交叉编译工具
    的头像 发表于 11-24 19:04 1173次阅读
    Linux 下交叉编译实战:跑<b class='flag-5'>起来</b>你的第一个 STM32 <b class='flag-5'>程序</b>

    CW32L010的安全运行库保护是什么功能?

    它是针对用户指定的MCU内部FLASH数据,提供的一种读保护功能;该功能生效后,就可以禁止对安全运行库进行任何形式的读取操作(比如CPU、 SWD、 ISP 均无法正确读取该区数据), 但不影响调用
    发表于 11-12 06:19

    蜂鸟E203能够仿真运行C语言程序吗?

    我看那两本书里面都是说怎么在FPGA上运行C语言程序和Benchmark程序,它提供仿真器下如何编译运行C语言程序吗?
    发表于 11-06 06:21

    Arm Neoverse CPU上大代码量Java应用的性能测试

    Java 是互联网领域广泛使用的编程语言。Java 应用的一些特性使其性能表现与提前编译的原生应用(例如 C 程序)大相径庭。由于 Java 字节码无法直接在 CPU 上执行,因此通常运行时在
    的头像 发表于 11-05 11:25 1012次阅读
    Arm Neoverse <b class='flag-5'>CPU</b>上大代码量Java应用的性能测试

    使用Nuclei Studio IDE计算程序运行时间

    在使用Nuclei Studio IDE进行程序运行时,我们想知道我们编写的程序运行时间有多长怎么办呢?可以选择调用IDE里面时间记录函数_gettimeofday(),该函数用于记录
    发表于 10-28 08:25

    大数组程序无法运行怎么解决?

    主控是103,程序中定义一个const类型 128k只读数组,放在flash上,程序无法运行,堆栈都初始化不了,在keil编译下正常,在rtthread studio下编译无法运行,求
    发表于 09-15 06:21

    CPU 到 GPU,渲染技术如何重塑游戏、影视与设计?

    CPU(CentralProcessingUnit)是计算机的中央处理器,它负责执行各种程序和指令。CPU渲染是指使用CPU来执行渲染流程
    的头像 发表于 09-01 12:16 1203次阅读
    从 <b class='flag-5'>CPU</b> 到 GPU,渲染技术如何重塑游戏、影视与设计?

    探索CPU架构的奥秘,揭秘高性能计算的隐形引擎

    的深海,揭开那些隐藏在高性能计算背后的神秘面纱。1.取指令(Fetch)程序计数器(PC):CPU通过程序计数器获取下一条指令的内存地址。指令读取:从存储器或缓存中读
    的头像 发表于 08-13 11:58 1020次阅读
    探索<b class='flag-5'>CPU</b>架构的奥秘,揭秘高性能计算的隐形引擎

    嵌入式系统中,FLASH 中的程序代码必须搬到 RAM 中运行吗?

    嵌入式系统里,FLASH 中的程序代码并非必须搬到 RAM 中运行,这得由硬件配置、实际性能需求和应用场景共同决定。就像很多低端单片机,无论是依赖片内 Flash 还是外挂的 SPI NOR
    的头像 发表于 08-06 10:19 1604次阅读
    嵌入式系统中,FLASH 中的<b class='flag-5'>程序</b>代码必须搬到 RAM 中<b class='flag-5'>运行</b>吗?

    单核CPU网关和双核CPU网关有什么区别

    单核CPU网关与双核CPU网关的核心区别在于处理能力、多任务效率、性能表现及适用场景,双核CPU网关在多任务处理、复杂计算和响应速度上具有显著优势,而单核CPU网关则更适合轻量级、低负
    的头像 发表于 07-05 14:37 1414次阅读