《操作系统真象还原》——0.16 为什么说汇编语言比C语言快

0.16 为什么说汇编语言比C语言快

首先说这是谬论(有没有想喷我的冲动?大人且慢,请听我慢慢道来)。

不管用什么语言,程序最终都是给CPU运行的,只有CPU才能让程序跑起来。CPU不知道什么是汇编语言、C语言,甚至Java、PHP、Python等,它根本不知道交给它的指令曾经经历过那么多的解释、编译工序。不管什么语言,编译器最终翻译出来的都是机器指令。所以在这一点来说,汇编语言编译器编译出来的机器指令和C编译器编译出来的机器指令无异。

那为什么还说汇编语言更快呢?

我觉得应该说汇编语言生成的指令数更少,从而“显得”执行得快,并不是汇编语言本身有多少威武霸气,而是因为汇编语言本身就是机器指令的符号化,意思是说,一个汇编语言中的符号对应一个机器指令,它们是一一对应的。用汇编语言写程序就相当于直接在写机器指令,汇编语言编译器并不会添加额外的语句,因此汇编语言写的程序会更直接,CPU不会因多执行一些无关的指令而浪费时间,当然会快。

再看看C编译器为咱们做了什么。为了让C程序员更加方便地编程,C编译器在背后做了大量的工作,不仅如此,出于通用性、易用性或者其他方面的考虑,C编译器往往会在背后加入额外的C语言代码来支撑,因此实际的C代码量就变得很大。另外在编译阶段,C代码会率先被编译成汇编代码,然后再由汇编器将汇编代码翻译成机器指令,由于C代码已经变得冗余了,编译出的汇编代码自然也会冗余,其机器指令也会多很多。

大多数人愿意用C语言写程序是因为C语言强大且更容易掌握。但这份优势是有代价的。C程序员不用考虑切换栈,不用考虑用哪个段。这些必须要考虑的事情,程序员不考虑,只好由编译器帮着考虑了。而且为了通用性、功能,甚至安全方面的考虑,自然在背后要多写一些代码。就拿打印字符串来说,C语言的printf(),这里面的工作可多了去了,不仅要检查打印的数据类型,还要负责格式,小数点保留位数……而在汇编语言中只要往显存地址处mov一个字符就行了,字符串也就是多几个mov操作而已。您说,C语言为了让开发者用得爽,自己在背后做了多少贡献。

总结:高级语言如C语言为了通用性等,需要兼顾的东西比较多,往往还加入了一些额外的代码,因此编译出来的汇编代码比较多,很多部分都是一些周边功能,并不是直接起作用的,不如用汇编语言直接写功能相关的部分效果来得更直接,C语言被编译成机器指令后,生成的机器指令当然也包括这些额外的部分,相当于多执行了一些“看似没用”的指令,因此会比直接用汇编语言慢。

时间: 2024-09-23 10:30:29

《操作系统真象还原》——0.16 为什么说汇编语言比C语言快的相关文章

《操作系统真象还原》——导读

**前言**想象一下,如果是爱因斯坦那样的天才给我们讲物理知识,我们会觉得物理更容易理解吗?肯定是不会的,因为在爱因斯坦眼中比较容易的内容也许对我们来说非常深奥,他用B解释A的时候也许会让我们更迷惑,因为B我们也不懂,这就是基础的问题了.幸运的是阅读本书时读者只要有C语言和部分汇编语言的基础就行了,涉及的其他方面的知识我都会详细介绍,并以更易懂的方式去解释技术难点,读者不必担心看不懂本书. 回忆一下学车的经历:教练让学员先踩离合器再挂档,然后再踩油门,车子就开动啦.如果学员总是学不会这些,有可能

《操作系统真象还原》——0.17 先有的语言,还是先有的编译器,第1个编译器是怎么产生的

0.17 先有的语言,还是先有的编译器,第1个编译器是怎么产生的 首先肯定的是先有的编程语言,哪怕这个语言简单到只有一个符号.先是设计好语言的规则,然后编写能够识别这套规则的编译器,否则若没有语言规则作为指导方向,编译器编写将无从下笔. 第1个编译器是怎么产生的?这个问题我并没有求证,不过可以谈下自己的理解,请大伙儿辩证地看. 这个问题属于哲学中鸡生蛋.蛋生鸡的问题,这种思维回旋性质的本源问题经常让人产生迷惑.可是现实生活中这样的例子太多了. (1)英语老师教学生英语,学生成了英语老师后又可以教

《操作系统真象还原》——0.26 库函数是用户进程与内核的桥梁

0.26 库函数是用户进程与内核的桥梁 在讨论此问题之前,我们应该明白此问题的始作俑者是操作系统本身.我们用了操作系统,就理应遵守它的规范.任何操作系统都有自己的一套做事规则,在其上的所有应用程序,都按照它定下的规矩做事. 我们讨论的环境是Linux,所以,以下所有的内容都是在Linux系统的规则之中讨论,我们所讨论的内容便是搞清楚这些规则. 在Linux下C编程时,我们写的程序通常是用户级程序.为了输出文本,我们一般会在文件开始include ,这样程序就可以使用printf这样的函数完成打印

《操作系统真象还原》——0.25 指令集、体系结构、微架构、编程语言

0.25 指令集.体系结构.微架构.编程语言 指令集是什么?表面上看它是一套指令的集合.集合的意思显而易见,那咱们说说什么是指令. 在计算机中,CPU只能识别0.1这两个数,甚至它都不知道数是什么,它只知道要么"是",要么"不是",恰好用0.1来表示这两种状态而已. 人发明的东西逃不出人的思维,所以,先看看我们人类的语言是怎么回事. 不同的语言对同一种事物有不同的名字,这个名字其实就是代码.比如说人类的好朋友:狗,咱们在中文里称之为狗,但在英文中它被称为dog,虽然

《操作系统真象还原》——0.8 代码中为什么分为代码段、数据段?这和内存访问机制中的段是一回事吗

0.8 代码中为什么分为代码段.数据段?这和内存访问机制中的段是一回事吗 首先,程序不是一定要分段才能运行的,分段只是为了使程序更加优美.就像用饭盒装饭菜一样,完全可以将很多菜和米饭混合在一起,或者搅拌成一体,哈哈,但这样可能就没什么胃口啦.如果饭盒中有好多小格子,方便将不同的菜和饭区分存放,这样会让我们胃口大开增加食欲. x86平台的处理器是必须要用分段机制访问内存的,正因为如此,处理器才提供了段寄存器,用来指定待访问的内存段起始地址.我们这里讨论的程序代码中的段(用section或segme

《操作系统真象还原》——0.7 内存访问为什么要分段

0.7 内存访问为什么要分段 按理说咱们应该先看看段是什么,不过了解段是什么之前,先看看内存是什么样子,如图0-2所示. 内存按访问方式来看,其结构就如同上面的长方形带子,地址依次升高.为了解释问题更明白,我们假设还在实模式下,如果读者不清楚什么是实模式也不要紧,这并不影响理解段是什么,故暂且先忽略. 内存是随机读写设备,即访问其内部任何一处,不需要从头开始找,只要直接给出其地址便可.如访问内存0xC00,只要将此地址写入地址总线便可.问题来了,分段是内存访问机制,是给CPU用的访问内存的方式,

《操作系统真象还原》——0.24 如何控制CPU的下一条指令

0.24 如何控制CPU的下一条指令 其实此问题我一直犹豫要不要写出来,因为大部人都觉得这个问题有些匪夷所思,CPU是负责执行指令的,它会按照程序的执行流程走,此问题的目的其实就是想知道如何牵着CPU的鼻子走.当初我被问这个问题时也觉得很诧异,甚至我觉得自己可能没理解人家的意思.后来他这样跟我说:"CPU要执行的下一条指令是在CS:IP寄存器吧?"我说:"是啊".他又问:"CS和IP寄存器,是用mov指令修改的吗?"我听后,顿时觉得他这个问题很有

《操作系统真象还原》——0.27 转义字符与ASCII码

0.27 转义字符与ASCII码 计算机世界中是以二进制来运行的,无论是指令.数据,都是以二进制的形式提交给硬件处理的,字符也一样,必须转换成二进制才能被计算机识别.所以各种各样的字符编码产生,简单来说,字符编码就是用唯一的一个二进制串表示唯一的一个字符.其中最著名的字符编码就是ASCII码. ASCII码表中字符按可见分成两大类,一类是不可见字符,共33个,它们的ASCII码值是0-31和127,属于控制字符或通信专用字符.表中其余的字符是可见字符,它们的ASCII码值是32-126,属于数字

《操作系统真象还原》——0.21 Section和Segment的区别

0.21 Section和Segment的区别 C程序大体上分为预处理.编译.汇编和链接4个阶段.预处理阶段是预处理器将高级语言中的宏展开,去掉代码注释,为调试器添加行号等.编译阶段是将预处理后的高级语言进行词法分析.语法分析.语义分析.优化,最后生成汇编代码.汇编阶段是将汇编代码编译成目标文件,也就是转换成了目标机器平台上的机器指令.链接阶段是将目标文件连接成可执行文件.这里我们只关注汇编和链接这两个阶段. 在汇编源码中,通常用语法关键字section或segment来表示一段区域,它们是编译