{eval=Array;=+count(Array);}

问答专栏Q & A COLUMN

所有的编程语言最后会编译成C,再编译成汇编,最后落实到硬件操作上吗?

DevYKDevYK 回答10 收藏1
收藏问题

10条回答

forsigner

forsigner

回答于2022-06-22 19:55

首先上结论:

(1)不是所有的编程语言都要先编译成C

(2)甚至有编程语言连编译成汇编这一步都跳过了。

(3)不是所有的编程语言都需要编译,有的是纯解释型语言

1. 编程语言到硬件执行之间到底发生了什么?

硬件执行的本质就是一堆电子元件的“开关”动作,开、关两种状态可以用二进制的1和0来表示,这样整个硬件的执行就和二进制对应了起来。硬件是无法理解上层的高级编程语言的(比如Java、C++、C,、C#、Javascript…… )。

那么为什么要发明高级编程语言呢?因为:

(1)人类直接与二进制打交道,比较费力,与自然语言相隔太远,不利于相互交流和协作,从而很难诞生高效的大规模团队协作来完成超复杂规模的软件设计、开发。

(2)每种硬件平台对应的二进制设计都不太相同,如果直接与二进制打交道,那么就要不断地重复造轮子,不利于跨平台的设计和协作。

既然需要高级编程语言,而硬件又只认识二进制,那么怎么去解决这两者之间的鸿沟呢?答案就是:编译和解释。

2. 编译是什么?

你可以把编译类比成一次性翻译完整的文学著作。相当于把用高级编程语言编写的源代码一次性转换成二进制。

人们摆脱二进制的第一步尝试是设计汇编语言和开发汇编器。每一条汇编指令与对应的二进制是一一对应的,换言之,汇编语言只不过是二进制的一种助记方式。

在有了汇编器之后,可以在汇编语言之上,再来设计高级编程语言和高级语言的编译器,后者可以通过汇编器转换成二进制。通过这样的不断递归的设计、开发过程,就可以设计出非常高级的编程语言。具体的原理分析可以参见笔者的专栏《ucloud方舟编译器源代码分析》的《先有蛋还是先有鸡:编译器本身是怎么被编译出来的?》。

只要有能转换出最终二进制的高级语言编译器,那么其实是不需要有显式的汇编器和汇编语言的。

3. 解释是什么?

解释相对于同声传译。Javascript这些脚本语言,大部分都是采用解释器来做翻译。它并不需要像编译那样,一次性把所有的源代码转换成最终的二进制。而是在运行的过程中,一边翻译一边执行。与上面设计高级编程语言的编译器的方式一样,高级语言的计时器也可以通过递归的方式设计、开发。到最后,只要有能转换出最终二进制的高级语言解释器,那么其实是不需要有显式的汇编器和汇编语言的。

关于解释器的具体原理,以及加强型算法——如JIT,可以参见笔者的专栏《ucloud方舟编译器源代码分析》的《干掉Java虚拟机来提升应用程序性能:只有ucloud想到了吗?》。

4. 一些直接面向高级语言的机器

历史上还专门开发过面向高级语言的机器,中间是不需要汇编语言过渡的。比如大名鼎鼎的LISP语言。曾经人们专门为LISP语言开发过对应的机器。但是最终的商业成果并不理想,主要是当时一些条件还不成熟。

评论0 赞同0
  •  加载中...
0x584a

0x584a

回答于2022-06-22 19:55

我来回答这个问题,其实际情况并不是这样的,首先要明确的是,我们不管用什么语言编写程序最后都要生成机器能够识别的语言。我以自已最为熟悉的编程语言C语言和汇编语言为例来说明吧!



我们知道计算机是不能直接识别C语言或汇编语言的,要经过编译软件把这些人类很容易读懂的语言生成计算机能够“识读”的语言,我们称之为“机器语言”。机器语言都是以“1”和“0”组成的,我们人类很难读懂!



因此,在用编程软件编写程序时,编程软件都有把源程序编译成目标文件的功能,比如我们常用的keil软件,只要通过简单的设置便会自动生成后缀为.Hex的目标文件,我们要把这个文件通过下载软件下载到计算机中就可以了!不需要相互转换。我们用汇编写程序也是一样的方法。不过所生成的目标文件其格式可以是.Hex文件或者.bin文件,只不过前者以十六进制形式出现而后者以二进制形式出现!我们可以类推出其它编程语言都应该大同小异。



当然,最后我们可以使C语言和汇编语言相互转化的,我们称为反汇编!这种方法用的场合较少!以上是我对这个问题的回答!欢迎朋友们参与讨论这个话题。敬请观注电子及工控技术!

评论0 赞同0
  •  加载中...
Karuru

Karuru

回答于2022-06-22 19:55

用C写的程序才会被编译成汇编语言,再由汇编器翻译成机器码。是这样的,要搞清楚一点,只有机器语言才能和底层硬件打交道,也就是每种高级语言的最终执行代码都是机器码,至于中间形式的目标代码则有很多种,像Java语言的代码被编译成一种叫字节码的中间代码,然后由相应平台的JVM翻译成机器码执行,还有的像JavaScript, Python这种解释型的语言根本就不经过编译,而是逐条代码直接翻译成机器码再执行。很多时候说C语言是最基础的语言并不是说所有语言都要往C语言上走一遍,一部分原因是因为C语言的特性使得它适合编写一些语言的底层支持模块,还有就是操作系统是由C语言编写的,应用程序与操作系统交互需要调用一些C写的模块。总之,你完全可以自己发明一种语言,你定义好语法规则,再写一个针对这种需要的编译器,能翻译成平台兼容的机器语言,那样就可以执行了。所以不存在什么语言都要转成C这一说

评论0 赞同0
  •  加载中...
FWHeart

FWHeart

回答于2022-06-22 19:55

java是编译成软指令,运行时由jvm就是java虚拟机翻译成本地硬件指令。而c语言编译后是直接的机器指令。

因此,在不同架构CPU和操作系统上实现不同的jvm就可以实现java库的跨平台使用。就是说只要你的平台能安装jvm就能运行java程序。

汇编语言是文本化的机器指令,任何语言一般不编译成汇编语言。

而汇编语言程序,编译之后才是机器指令。

机器指令都是二进制存储的,具体每条指令形态就像:指令id+参数,参数就像是寄存器、立即数这样的。指令id就是某条指令唯一的标识。

指令id一般由CPU厂商给出列表,说明哪个数字对应于哪个指令。

评论0 赞同0
  •  加载中...
mingde

mingde

回答于2022-06-22 19:55

  • C是最接近CPU指令集的高级语言,几乎没有多余的东西。
  • 小到玩具、大到超级计算机,各种CPU的指令集在本质上差不多。

所以很多涉及底层的东西是用C写的,既有较高性能,又相对容易移植。

比如Python是用C语言写的,但是Python程序在运行时不会被编译成C语言。

C++是给C语言添加了面向对象的概念。

评论0 赞同0
  •  加载中...
antz

antz

回答于2022-06-22 19:55

实际情况并不是这样的。

我们来一条条的看吧:

1.编程语言并不是都要编译成C,这个说法不知道是谁提出来的。C语言和java,python一样,也是一种高级语言。但是C语言有个优势,就是可以嵌套汇编,实现底层交互。

2.很多人存在一个误区,汇编语言就是最底层的语言了,其实计算机还是不认识汇编是个什么东西, 因为计算机只能识别一种语言,那就是机器语言,全都是0和1这样的二进制数。比方说MOV AX,BX,这条汇编的意思是寄存器将BX的内容转移到AX中,对应机器语言的1000100111011000,非常复杂。可以这么理解:汇编语言实际上是机器指令的一种简写形势。

可以看看下图,做一个简单的加法运算,分别用C语言,汇编和机器语言表示,各位就能理解高级语言的好处了。

无论是C还是其他什么语言,最终的目的都是实现某种功能,而这离不开硬件的支持,所以归根结底,还是要从程序和硬件的关系说起。

硬件,程序和编译器之间的关系

在计算机中存在着大量的电子元件,电路就两种情况:开和关,这两种状态分别用1和0来表示,也就是众所周知的二进制, 在计算机中,所有的运算都是以二进制的形式进行的,比方说3+4,在CPU中的表现形式为00110000+01000000,如果是负数运算或浮点运算的话还会更复杂一些,这里不再累述。

通过0和1决定电路状态,那么操作者是通过编程语言操作硬件的呢?这里编译器的作用就体现出来了。

编译器就像是一个翻译一样,也就任人们口中俗称的编程软件。其实用更专业的话来说,编译器实际上是IDE(开发集成环境)中的一个工具。

虽然大家可能在操作中感受不是那么强烈,但如果你在windows控制台下用javac编译过java代码,或者你在linux的命令行下编译过程序,这个时候我们就直接使用了编译器。

最后提一点,并不是所有的语言都会被编译器直接编译成机器语言。C语言是一个比较特殊的语言,因为他是直接可以直接编译为汇编再编译为机器码的,这也是C语言可以和底层打交道的主要原因。像我们熟知的java,它会把源码先转换成一种叫做字节码的东西,通过JVM虚拟机将其转换为机器码。所以说,编译器的类型有很多,作用不能一概而论。

评论0 赞同0
  •  加载中...
levinit

levinit

回答于2022-06-22 19:55

我认为只是一小部分很low的高级语言需要C语言中转编绎。大多数PC机语言直接编绎成宏汇编语言或者更直接的机器语言的形式执行;而更低级的单片机语言,无论是C还是汇编,都直接编绎为机器码,直接可被设备识别。



像高级的C++语言,如果进行调试,基本以宏汇编语言的形式出现,VC,VS等基本如此。当然,要让机器识别,最后必然是机器码。

也有很多很low的高级语言,必须先转为C,再执行。这种语言效率都很低,可以理解为2次开发。这也是为什么很多小公司、个人都可以做编绎器,小范围、特定场合用用可以。

对于单片机编程,简单很多。这也是为什么单片机编绎程序众多的主要原因。特别是最low的51系到8位程序的编绎,初学者都可以尝试做。当然做到极致也是不容易的。




编绎语言,要做到微软MS的VC,VS的水平,估计需要几十年的努力,同时还要对处理器的硬件结构搞的很明白。如果相关的知名处理器厂商,如Intel,ARM架构等厂商不跟你合作,估计永远也做不出来。



(图片来源于网络,仅为示意)

评论0 赞同0
  •  加载中...
Caicloud

Caicloud

回答于2022-06-22 19:55

首先这种认识是不正确的,所有的编程语言要转化成机器语言然后才去运行,肯定不会转化成C语言去运行,因为C语言还是要汇总成机器语言去运行。从类别上讲编程语言主要分成两种,一种在运行之前提前生成二进制文件,机器上电直接运行就可以了;另外一种是一边运行一边编译最终的结果也是转化成二进制文件,这样机器才能准确的识别出来。只要是遵循冯诺依曼的架构都要转化成二进制的文件让机器去运转执行,可能在未来量子计算机发展起来架构会有所改变,起码在很长的一段时间内还会继续这种架构存在。

编程语言如何实现跨平台运行

就拿典型的编程语言Java作为例子来阐述,java属于典型的跨平台语言,跨平台的语言编程的好处是在任何一个操作系统上完成代码编写之后就可以在任何平台来运行,一般开发java都在windows平台上开发,但真正在部署的时候既可以在linux服务器上运行,也可以在windows服务器上运行。但在实际运行过程中还是要遵循各自的指令体系,做这个时期的关键点就在于java的虚拟机,所以在安装运行环境的时候,不同的操作系统的版本是不一致的,java在编译的时候都会转化成字节码,字节码在不同操作系统的虚拟机都可以运行,虚拟机里面会把主流的操作系统指令都分别集成进去,也就是java版本在更迭的时候除了增加基本语法之外,还要在修改不同的操作系统底层实现,这样子才能真正做到跨平台运行。

跨平台在嵌入式领域使用的比较多,如果用C++开发的代码可以在宿主机上直接运行,调试完毕了然后再烧录到嵌入式板卡里面去运行,毕竟直接在PC的linux上调试代码,要比直接在板子里调试要方便的多,这就是跨平台的好处,除了方便开发代码还极大方便调试。

C语言在编程语言中的地位

虽然不是每种编程语言都要转化成C语言再去运行,但很多编程语言的底层都是C语言来实现的,这是真实存在的事实,但还是有很多人觉得C语言已经过时了,起码从招聘的简章C语言的比例在下降,这个主要原因是国内程序员大部分都做着互联网的工作,互联网主要从事应用级开发比较多,所以一些集成化编程语言在国内比较能够吃得开,像python,php,Java在国内都有着良好的生态基础,这是国内软件环境决定的。

C语言在很多基础领域还是首选的编程语言,语法简洁但灵活多样,在实际功能的的时候效率高性能强,在很多领域还是第一编程语言,主要在通讯行业以及嵌入式领域还是C语言的主战场。非常流行的人工智能在底层很多功能实现也是基于C语言完成,只不过C语言的角色从前台走向了幕后,但重要性并没有因此而降低,即使选择C语言作为入门的编程语言,在基础过硬的情况下照样能找到合适的工作,不要迷信C语言已经不行了之类的话语。

对于编程语言的编译原理以及运行过程还是要多去涉猎,如果纯正的高级编程语言可能很少去关系这些个原理,都是去操心如何架构等方面的问题,底层如何实现功能对于上层调用方式都有决定性因素,尽管很多人不推荐第一门编程语言选择C语言,但从个人的角度出发,还是建议C语言作为入门编程语言,即使不是从事这方面的工作,起码在从知识体系上还是有很大的好处,希望能帮到你。

评论0 赞同0
  •  加载中...
legendaryedu

legendaryedu

回答于2022-06-22 19:55

你可能听错了 大部分编程语言是用C开发的 例如大行其道的Python和Java 但是并不是说这些语言一定会编译为C 往往是编译成虚拟机指令或者编译成机器语言 注意机器语言不是汇编语言 机器语言是二进制可以直接执行

以Python为例 Python本身的编译器会把源代码编译为虚拟机的指令 再用虚拟机去执行这些指令 Python的一大优势是很容易呼叫C规格的共享函数库 或者说很容易用C来扩展或者加速Python

单纯就虚拟机来比较 Java虚拟机更优秀 很多新技术 例如JIT编译技术

不过Python+C的组合还是很有市场 特别是人工智能和工业控制 还有自动化部署和测试自动化

如果你想了解虚拟机 SQLite虚拟机相对比较简单 虽然是个数据库虚拟机 不过文档比较容易消化 代码也就一个C文件

评论0 赞同0
  •  加载中...
stackfing

stackfing

回答于2022-06-22 19:55

计算机能够识别的语言只有机器语言,也就是0-1代码,咱们可以直接编写0-1代码让计算机执行程序,没有问题。但是,这就增加我们学习编程的学习成本和编程成本,为此咱们的前辈们开发了编程语言,最早的是汇编语言,通过编译器将汇编语言变成机器语言;另外一种是高级语言,像Python、java、C++、MATLAB、VB等等。高级语言接近于人类语言,学习成本、编程成本低,汇编语言学习成本较高,目前除了对计算速度要求极其严格的环境,一般不采用汇编语言。

因此,高级语言和汇编语言不是递进的关系,即高级语言不会编译成汇编语言,他们都会变成机器语言(即0-1代码),供计算机硬件识别并驱动计算机完成相关功能。

评论0 赞同0
  •  加载中...

最新活动

您已邀请0人回答 查看邀请

我的邀请列表

  • 擅长该话题
  • 回答过该话题
  • 我关注的人
向帮助了您的网友说句感谢的话吧!
付费偷看金额在0.1-10元之间
<