CPU是怎么认识代码的?

邢小燕


我目前是微电子研究生在读,偏工艺方向,个人了解的整个计算机的产业是:硅片--->元器件(MOSFET)--->设计的电路(阵列,阵列上每个点是元器件)--->整个硬件系统--->操作系统--->编译器--->高级语言(C语言,python等)--->用户。我们都知道代码是二进制的,只能识别“0”和 “1”,这是由于最底层的元器件所决定的。所以关键是搞懂最底层的元器件是如何实现与二进制”0“和”1“的相对应的。

芯片上的元器件(MOSFET)

这个元器件是MOSFET,叫做金属氧化物半导体场效应晶体管,MOSFET主要有source(S,源极),drain(D,漏极),gate(G,栅压)组成,主要的工作原理是通过加栅压电场来实现源极和漏极之间的导通,当源极和漏极导通的时候就对应于二进制里面的”1“,源极和漏极之间没有导通的时候就对应于二进制里面的”0“,所以这个阈值(临界)电压很重要。达到阈值电压就导通,达不到就是不导通。

电路设计

上面只是讨论了区别”1“和”0“,而能够区别不同功能的,是在电路层面进行设计,这就要通过不同的逻辑”与“门,”或“门,”非“门来实现,是否对某一个器件进行通电流。通电就是对应于”1“,不通就是高阻态对应于”0“。

操作系统和编译器层面

操作系统和编译器就是将高级语言转换成一系列二进制的数字,一串不同的二进制数字,通过操作系统来控制硬件上的不同功能。

最后附上一张整个计算机体系的图:



大概简单的科普一下,希望对你有所帮助,后续会写相关的文章,欢迎有补充的朋友评论区留言交流!


物理微电子前沿科普


如果你是一个程序员,你写过很多代码,那么现在要你写一段程序,计算50.00*0.1的值。

你也许会这样写:

代码你很快写完了,如果没有和其他人交流,可能只是你自己看了,而抱歉的是CPU也不认识你写的是啥。

CPU并不认识你写的程序

CPU不知道也不管你是用什么语言写的代码,那是给人阅读的,不是给CPU阅读的,CPU只懂得编译过的二进制指令,也就是一大串的0和1,还必须按照商家设计好的指令体系编制的指令序列才行。至于你写的那些牛B的代码,CPU并不买账,它好不好用在于编译器或解释器把这些人类代码翻译为机器码有多高明。

那CPU是怎么去执行我们的程序呢?

这就是编译器存在的原因了,编译器将我们写的程序编译成可供CPU执行的二进制代码,并且分配指令和内存的地址等这类复杂的工作。

程序大体的执行流程

一个程序的执行流程总体上可以分为3个步骤:磁盘->RAM(内存)->CPU

即程序从磁盘拷贝到内存中,CPU从内存中取指令,然后解码,之后执行,最后将执行结果写回内存。

CPU又是如何执行指令的呢?

硬件产商约定好了一套指令体系,不管什么编程语言都通过某种方式把代码编译为CPU能懂的二进制指令指挥CPU工作。

比如:有一串指令过来了,如果是以1开头,则表示做什么,比如做加法,那么后面接着会发过来两个数,CPU做加法后把结果存入既定的寄存器,程序会有后续的指令去这个寄存器提取结果,放入指定的内存中。CPU就是按照这样的约定解析传入的一连串的二进制数据,并一一的去执行。这就好比航海的船通过约定的灯语(灯的有规律亮、灭)来相互通信的道理是一样的。

总结

所以说,CPU不是认识代码,而是记住代码,数据总线送过来一个指令,是什么要如何去执行,已经固化在了CPU里了。如何执行和固化?是通过复杂的组合,以门、非门、与非门这三种复杂的组合,实现了复杂的逻辑关系。

以上是我个人的一些经验和总结,希望可以帮助到大家,如果有不同意见可以评论区留言一起讨论。


汇聚魔杖


我是电子及工控技术,我来回答这个问题。作为中央处理器的CPU是无法识别我们人类编写的程序代码的,而CPU所能够识别的“语言”其实很简单,就是由“1”和“0”组成的数字串。而由“1”和“0”组成的数字串对于我们人类来说“读懂”它的含义也会感觉到一脸的茫然。鉴于这种在人脑和电脑CPU两者无法直接“交流”的情况下,人类又一次发挥了他极具创造性的想法发明了编译器。编译器的出现搭起了人类大脑和电脑CPU的沟通的桥梁与纽带。

由于CPU是一个极为庞大的集成电路,为了说明问题我们用其中一个极为简单的数字处理电路为例来说明CPU是如何“认识”我们人类编写的代码的。我们知道CPU中包含着数量众多的绝缘栅晶体管(MOSFET),在这些众多的绝缘栅晶体管(MOSFET)中分为两类,一类是P沟道的绝缘栅晶体管、另一类是N沟道的绝缘栅晶体管。

对于P沟道的绝缘栅晶体管来说,当给它的输入端加一个“1”时(高电平)时该管子就会处于“关闭”状态,当给它的输入端加一个“0”时(低电平)时该管子就会处于“打开”状态。

对于N沟道的绝缘栅晶体管来说,当给它的输入端加一个“0”时(低电平)时该管子就会处于“关闭”状态,当给它的输入端加一个“1”时(高电平)时该管子就会处于“打开”状态。因此根据这些MOS管的特点在任何一种输入条件下PMOS和NMOS都不会处于打开的状态。因此在CPU中就有用这些MOS管组成的与非门电路和或非门电路。因此就可以执行逻辑运算,所以说逻辑运算也是CPU的功能之一。

那么下一个问题是我们使用计算机语言编写的程序,比如常用的C语言或者汇编语言等等都有逻辑表达式或者逻辑指令,编写好一个逻辑运算的程序后要通过刚才讲的编译器对源程序进行编译生成CPU能够识别的“语言”(二进制代码)。又由于这个机器语言(二进制代码)与我们编写的逻辑运算程序是一一对应的,因此只要把这段代码“灌进”CPU的内部他就会按照我们人类的要求运作起来了,从而也就能够“认识”我们人类所写的代码了。

通过以上的简单实例给朋友们再现了CPU是怎么认识代码的过程的,我们通过“管中窥豹,时见一斑”的方法希望能给有疑惑的朋友提供一个参考答案,如有阐述不周之处希望朋友们批评指正。

以上就是我对这个问题的看法,欢迎朋友们参与讨论,敬请关注电子及工控技术,感谢点赞。


电子及工控技术


其实,CPU也不知道我们敲得代码是什么意思。想要让一段代码编程可执行的程序,需要进行一系列的操作。

关于CPU识别程序的问题,细讲起来是比较麻烦的一件事情,我们来分步骤逐一解释。

1.CPU的基本工作原理——数字电路

在具体将这个问题之前,我们先来了解一下半导体的特性。

顾名思义,半导体就是一种介于导体和绝缘体中间的物质,它具有以下特性。

比如上图,如果电流是从A端流向C端,则电路通畅;反过来的话就不行了。大家可以把它理解一种单方向控制电流的设备。

电流只有两种情况:开路和闭路,将开路规定为0,闭路规定为1,这也就是我们所熟知的二进制。

根据这种特性,设计者们开发出了“与”,“或”,“非”,“异或”四种情况:

  • 与门:只有同时具备条件A和条件B时,才能得出结果1,当其中任意一个条件为0时,结果为0。

1+1=1; 1+0=0; 0+1=0; 0+0=0

  • 或门:只有条件A或条件B都为0时,才能得出结果0;当其中任意条件为1时,结果为1;

1+1=1; 1+0=1; 0+1=1; 0+0=0

  • 非门:就是相反的意思,条件A的反为B,条件B的反为A;

输入x 输出y

0 1

1 0

  • 异或门:当两个条件取值相异(0和1)时,结果为1;反之为0

1⊕1=0;

1⊕0=1;

0⊕0=0;

根据这几种门电路,还衍生出了一些电路,比如与非门,或非门等等。但基本的电路状还是不会变的。这些门电路构成了CPU的基本工作原理——数字电路。

无论是数据的计算,还是指令的调度,CPU都是要通过运算来实现的。门电路的目的就是为了通过控制电流的状态,来实现计算的原理。当然了CPU上的电路是非常复杂的,如何将由门电路构造成的加法器,乘法器之类集成到一块指甲盖大小的电路板上绝非易事,这也是为什么芯片技术被称为最难突破的尖端技术的主要原因之一。

在简单了解CPU的工作原理后,就是关于高级语言和机器语言的转换问题了

机械语言和高级语言

早期的计算机编程是一件非常痛苦的事情,只要涉及到需要位移量的运算时,例如乘法运算,就要做大量的插线工作。也许一个几分钟就能算完的程式,插拔线路就得花上半个小时,还不能插错,否则就白忙活了。所以当时做这些工作的都是一些靓丽的摩登女郎,穿着漂亮的制服以缓解工作人员的压力……

随着计算量不断地增大,这种插拔的方式已经满足不了实际需求。,人们开始考虑:能不能设计一种语言来更高效的设计程序呢?由此,高级语言诞生了。

高级语言:一种接近于人类自然语言的表达方式,通过一些较为直观的单词,符号来表示低级语言。从而使编程变得明了易学,可读性强。

同时,高级语言分为面向过程和面向对象两类。前者在同一个功能每实现一次,都得重新编写一次代码,所以代码的重复利用率比较差;后者面向由于引入了类的概念,只要只要编写一次代码,后面便可以通过调用类的方式多次使用,大大提升了效率。所以java能成为最受欢迎的编程语言不是没有道理的。

机器语言:计算机最原始的语言,全部由0和1构成的数字串构成,也是cpu唯一可以识别的语言。

另外,还有一种汇编语言,很多人存在一个误区,觉得汇编语言就是机器语言,其实不然,CPU还是不知道汇编语言是个什么东西。汇编语言本质上还是一种计算机低级语言,通过汇编语言我们可以了解CPU 到底干了些什么,以及代码的运行步骤。

如何将高级语言转换成计算机可以识别的机器语言呢?这时候就需要编译器的发挥作用了:

简而言之,编译器就像是一个中转平台,就是将程序员使用的高级语言翻译为计算机可以识别运行的机器语言。其主要工作流程可以具象为:源代码 (source code) → 预处理器 (preprocessor) → 编译器 (compiler) → 目标代码 (object code) → 链接器(Linker) → 可执行程序 (executables),也就是我们最终使用的后缀名为.exe这样的程序。

最后说个题外话,编译器对于程序的所起的影响可谓举足轻重,甚至可能影响到CPU的执行效率。所以现在厂家除了绞尽脑汁的提升CPU性能外,也将目光投向了编译器,编译器极有可能在未来成为新的热门导向。



爱思考的奥特曼


提前备注:回答比较硬核,我会尽量软化,但想了解知识还是需要耐心。CPU内传输的信号有两种:高电压和低电压,分别代表数字信号“1”和“0”,因此CPU唯一能理解(问题中的“认识”)的语言就是由“1”和“0”写成的机器语言。

由于程序(代码)存储在电脑硬盘中时,也是“1”和“0”的形式,是否就意味着,只要程序存到硬盘中,CPU就能认识呢?

答案是CPU仍然看不懂这些程序,因为以“1”和“0”形式存储的程序和以“1”和“0”写成的语言完全是两回事,两者的区别类似于汉语书和英语书都用纸和油墨印制,但依然是两种不同的语言,不会英语的依然看不懂英语书。

要让CPU能看懂代码,要做相当多的工作。

现在的程序都是由C++和Java等高级语言写成,这些语言是为方便人类编程发明的,不是为方便电脑执行而设计。

说到这里,需要进一步说说机器语言和高级语言的差别。机器语言的最大特点是面向计算机硬件编程,简单说就是程序员需要通晓计算机硬件知识,写的程序要真实表示数据是如何被计算机操纵的。对程序员来说这就比较头大,毕竟上得了“厅堂”下得了“厨房”只有少数大神能做到,加上机器语言纯用“0”和“1”序列组成,既对视力是一种摧残,也是对编程趣味的扼杀。

于是,有一帮人开始琢磨了:能不能将计算机硬件从编程中分离出来,让硬件知识小白也能编程?

最先开窍的是蓝色巨人IBM,它在其System/360计算机中引入了ISA(Instruction Set Architecture)概念,将编程所需要了解的硬件信息从硬件中抽象出来,这样编程人员就可以面向ISA编程。由于ISA是用来描述编程时用到的抽象机器(不是具体的电脑CPU),包括了一套指令集和一些寄存器,因此,程序员只要知道ISA,不需要了解具体的硬件知识(每一两年硬件都会换新),就可以编写程序,在ISA相同的电脑上运行。

这样一来,程序员不必了解过于专业的计算机硬件知识,不需要下得了厅堂,可以专心在“厨房”烹调程序大餐。

由此也可以看出,程序员很多都是不了解计算机硬件的,所以妹子们不要指望自己的程序员男朋友给你DIY电脑,或者电脑坏了,他能给你省下一笔修理费。他说不会修,那就是真的不会修。

极客漫画《编程语言之战》。


自从不用懂硬件也能编程的高级语言出现后,人类开始了编程上的放飞自我,经过数十年发展,高级编程语言已超过2500种。

但矛盾出现了,CPU能理解的机器语言还是那个机器语言,几十年来没有变化,怎么办?

其实,早在高级语言出现之前的汇编语言时代,聪明的计算机研发人员就开发出了专门的程序,用来将汇编语言和高级语言翻译成机器语言,其过程相当于将英语名著翻译成汉语著作。这种翻译程序相当于人类中的翻译家。

编译器有两种方法用于翻译:编译和解释,相应的名称是编译器和解释器。

两者的区别是,编译是在执行前把整个源程序(高级语言程序)翻译成目标程序(机器语言程序),而解释是一次只翻译和执行源程序中的一行。

打个形象的比方,解释器相当于发布会的实时翻译,演讲的嘉宾说一句,实时翻译马上翻译一句。编译器则相当于著作翻译家,整本翻译完成后,再让出版社印刷上市。

将高级语言翻译成机器语言的过程。个人手绘比较粗糙,大家凑合看。


重点来了,从以上的内容可以看出,由于CPU不能直接理解用高级语言写成的代码,必须由翻译程序翻译成机器语言,因此翻译程序可以极大地影响甚至决定处理器性能的发挥。如果没有一个好的翻译程序,那么CPU的性能再强大,也好比茶壶装的饺子,倒不出来。

正因为如此,谷歌在安卓4.4之后,抛弃了Dalvik虚拟机,改为ART,实际是将翻译程序从解释器切换到编译器,发挥了芯片的性能,提高了程序运行效率。

现在,手机大厂包括华为、OPPO和vivo都开始重视编译器开发,说到底就是为了发挥芯片性能,让它不再成为倒不出饺子的茶壶。

最后总结一下,用翻译程序把程序员编写的程序翻译成二进制代码的机器语言后,CPU就能认识了,而且翻译程序的优劣可以影响乃至决定CPU性能发挥。


魔铁的世界


什么是代码?代者,替换也。

假如你设计一个数字电路,包括一个加法器和一个乘法器。

你希望根据需要,有时对输入数据做加法,有时对输入做乘法,该怎样做呢?

显而易见的方法是手工控制加法器和乘法器的使能端,每次只让一个电路工作。那么当两个使能端为01,就是加法器工作,是10,就是乘法器工作。

然后为了让电路根据要求的顺序做加法和乘法,你把一系列01、10存储起来,当你要做加法,加法,乘法,加法时,存储的就是01011001。你增加了一个时序电路,每次读出两个位,把高低电平加在两个使能端上,替代你的手工接线。01和10这两个数码能控制电路的行为,起名叫机器码。

然而这样二进制的东西并不好记忆。于是你给01起了个名字,叫add,10起名叫mul。你的这组运算就记为add,add,mul,add。

add,mul这种助记符,就叫代码,具体说是汇编代码;你会找一个悲催的助手,帮你把代码替换成01,10这种机械码。

由代码翻译成机器码的过程,后来也由机器来做,这种机器(软件)就叫编译器。

因此所谓cpu认识代码,是一种拟人化的修辞,偏文艺了。cpu只是一种根据高低电平输入,产生特定的高低电平输出的机器。代码不过是助记符。

后来你觉得add,add,add,add,add这类写法太烦,于是发明了五连加,7连乘之类的写法——高级语言代码诞生了。


味冷


CPU其实只认识“0”和“1”

我们经常会听说到某某芯片由多少百亿个晶体管组成这样的科技新闻。没错,CPU就是超大规模的集成电路,由数量超级多的晶体管组成,而晶体管只有“开”和“关”两种状态,刚好可以用“0”和“1”来代表这两种状态,所以CPU是采用二进制来进行运算的。

CPU是什么?

CPU是Central Processing Unit的缩写,中文名全称为中央处理器。CPU的组成包括了运算逻辑、寄存器和控制部件,它可以解释指令和进行数据运算处理。因为CPU本身就是超大规模的数字电路,只认识“0”和“1”,所以所有的指令和数据都需要由“0”和“1”组成。

二进制只有“0”和“1”怎么运算?

所有运算逻辑我们都可以理解为“与”,“或”,“非”,“异或”四种哦

与门:多个条件中,所有条件成立才算成立,

  • 1 and 1 = 1
  • 1 and 0 = 0
  • 0 and 0 = 0

或门:多个条件中,只要有一个条件成立,就算成立

  • 1 or 0 =1
  • 1 or 1 =1
  • 0 or 0 =0

非门:其实就是反相

  • not 1 =0
  • not 0 =1

异或门:可以理解为,两个条件不一样,才算成立

  • 1 xor 1 =0
  • 1 xor 0 =1
  • 0 xor 0 =0

当然还可以由这四种门延申出“与非门”,“或非门”,“与或非门”,“异或非门”等。

CPU为什么可以运行我们的程序呢?

上面说到CPU只认识“0”和“1”,那它为什么可以运行我们的程序呢?CPU的确不可以直接运行我们编写的程序。但如果直接只用“0”和“1”的组合来写程序,那是相当的烦所,也难以找到错误,是非常不现实的。聪明的人类为了解决这个大麻烦,就发明了汇编语言,用一些容易理解和记忆的字符来代替“0”和“1”组成的指令。

例如:

  • ADD:表示逻辑加减
  • MOV:代表数据传递
  • JMP:代表跳转

当然还是需要通过汇编器把这些用汇编语言编写的程序翻译为“0”和“1”组成的十六进制机器码。

随着计算机技术的发展,写的程序也越来越复杂了,发现用汇编语言编写程序的效率也相当低,然后聪明的人类又发明了我们现在用的各种高级语言,比如C,C++,PHP,Python等等,当然这些由高级语言编写的程序就需要通过编译器"翻译"为CPU能够识别的十六进制机器码。

汇编器或者编译器可以理解代码与CPU沟统的“桥梁”了,通过它进行“翻译”,CPU就可以认识代码了。

欢迎关注@电子产品设计方案,一起享受分享与学习的乐趣!关注我,成为朋友,一起交流一起学习

  • 记得点赞和评论哦!非常感谢!

电子产品设计方案


你看看海上船只之间通过打灯光沟通是怎样的,CPU执行代码也是那个原理。

关键是约定一套信号协议。CPU只按传入的二进制代码执行指令,商家约定好了一套指令体系,不管什么编程语言都通过某种方式把代码编译为CPU能懂的二进制指令指挥CPU工作。协议跟人与人的交流一样,是有规矩的。举个例子,发出一串指令,如果是以1开头,则表示做什么,比如做加法,那么後面接着会发过来两个数,CPU做加法後把结果存入特定的寄存器,程序会有後续指令去这个寄存器提取结果,放入指定的内存中,CPU按照这样的约定解析传入的一连串二进制数据,并一一执行。CPU能直接做什么,根据这套指令体系来,不能直接做的,程序员负责编写完整解决方案让CPU能做出来,这就叫编程,整个指令序列叫程序。

CPU不认识你什么语言代码,那是给人阅读的,不是给计算机阅读的,计算机只懂编译过的二进制指令,还必须是按照商家设计好的指令体系编制的指令序列才行。没有什么编程语言是高大上的,它好不好用,在于编译器或解释器把这些人类代码翻译为机器码有多高明,守恒律在这方面仍然起作用,你写的高级语言代码越少,翻译给机器执行的指令实际上越多。C入门最基础的hello world程序,不要以为写的很短就很得意,这程序编译後的二进制机器码有5K,printf()函数的源代码有多长,可以自己去看看,但实际上你输出一个字符串用不着完整的printf()功能,这函数其实一个低效的解释型程序。


TonyDeng


简而言之,就是有个编译器它知道目标cpu里指令执行单元能够去执行的各样用途的指令,加减乘除余比较移位…这些指令是一堆0110...,非人类,难搞!!!同时这个编译器也懂得你当前代码的语言规则,于是在你编译代码的时候帮你等价置换成了一堆那些难搞的二进制代码!CPU执行这些二进制代码的时候就相当于在复现你当时用编程语言表达的程序意图。这就是:你的代码 编译器 cpu


Virfri


准确的说,CPU不是认识代码,而是记住代码,数据总线送过来一个指令,是什么如何执行,已经固化在CPU里了,如何执行和固化?是通过复杂的组合,以门,非门,与非门这三种复杂的组合,实现了复杂的逻辑关系。


分享到:


相關文章: