内容简介:“哇塞,怎么可能这么简单!”当C语言老头儿还是小伙子的时候,第一次见到了汇编,发出了这么一声感慨。在C语言看来,这汇编的指令实在是太简单了,简单到了令人发指的地步,只有这么几类指令:
“哇塞,怎么可能这么简单!”
当 C语言 老头儿还是小伙子的时候,第一次见到了汇编,发出了这么一声感慨。
在C语言看来,这汇编的指令实在是太简单了,简单到了令人发指的地步,只有这么几类指令:
数据传输类:
就是把数据从一个位置复制到另外一个位置,比如从内存到寄存器,或者从寄存器到内存, 或者从寄存器到寄存器。
算术和逻辑运算类:
无非就是加减乘除,AND, OR, 左移,右移
控制类:
比较两个值,跳转到某一个位置。
汇编老头儿非常地骄傲, 他经常嚣张地说:“别看我的指令这么简单,但是配合我的寄存器和内存, 却能完成你们这些所谓的高级语言的所有功能!”
这寄存器是什么鬼? C语言脑海中只有内存和指针,根本就没有什么寄存器的概念, 实际上,这是属于CPU阿甘的,容量有限,但是速度超级快的存储部件。
32位CPU寄存器
图片来源: http://pascalturbo.net/cpu-registers/
数组
C看着汇编这单薄的小身板,想到自己那优雅的if , 漂亮的while, for ,还有那极为重要的函数调用,心里不由得泛起嘀咕:我的程序怎么可能被编译成这么简单的汇编?
虽然心里有点瞧不上,但C小伙还是挺恭敬的:“前辈,在我这里有个数组的概念,编译成汇编是什么样?”
int num[10];
num[0] = 100;
num[1] = 200;
除了机器语言,那就属汇编最老,连C语言的第一个编译器都是用汇编写的,当之无愧的前辈。
汇编老头儿没想到C小伙儿连这个问题都没弄清楚,说道:“我这里只认寄存器和内存,你这所谓数组,就是内存的一段连续的空间嘛,我只要知道开始地址就可以了。”
C小伙儿一看,好家伙,连变量名num都不要了。 不过说得也是, 汇编老头只要记住初始地址,顺着地址就能找到所有东西。
“咦,这个什么0x000083d0不就相当于我的指针么? ”
“是啊,不过在我这里,都是地址,忘掉指针吧!”
条件分支
C小伙又想到了自己的if else,在汇编中该怎么处理?
if(x < y ){ return y - x; } else { return x -y ; }
汇编老头儿说:“你们这些高级语言啊,就爱搞复杂化,怎么不用goto呢?”
C小伙说:“goto 被迪杰斯特拉认为是有害的,会破坏结构化,不建议使用!”
“唉,简单就是美,你们这些高级语言懂不了,我这里很简单,就是比较和跳转指令,从一个地方跳到另外一个地方执行就行了。”
汇编老头儿一遍感慨,一遍写道:
我们假设
%eax 寄存器保存的是y的值,
%edx 寄存器保存的是x的值。
cmpl %eax, %edx ; 比较x和y jge .L1 ; 如果x >= y,跳转到.L1处去执行 subl %edx,%eax ; 计算y-x,结果存到eax寄存器中 jmp .done ; 跳转到.done标签处 .L1: subl %eax, %edx ; 计算 x-y movl %edx, %eax ; 把结果存到eax寄存器中 .done: ; 计算结束,结果保存在eax寄存器中
(码农翻身注:这个例子来源于《深入理解计算机系统》)
C小伙儿看了半天,终于搞明白了这段汇编程序的含义,这所谓的jge也就是做一个判断,然后跳转到特定位置去执行,就像是if 和 goto 的结合。
汇编老头儿看到C小伙儿懂了, 问道:“你想想你的while 循环,for 循环,是不是if 和 goto 的包装而已?”
C小伙儿想了一会:“确实是这样!”
“这不就结了,我的汇编看起来简单,但是却能表达你所有的流程控制语句,不管什么if else, while, for ,switch ,对吧?”
C小伙儿觉得汇编老头儿说的都是歪理:“这goto是简单,可是程序读起来就非常复杂了啊!”
汇编老头儿说:“你算是说道了点子上,所谓高级语言,主要是方便人类的编写和阅读的,是为了提升人类的效率。 在我这里,主要是让CPU阿甘执行的,那傻小子,速度飞快,什么也不懂,你只要告诉它指令就行,越简单越好。”
没想到CPU阿甘听到了对它的嘲讽,不满地说:“老伙计,又在背后说我的坏话,我执行了亿万条指令以后,早就悟出了程序的局部性原理,这你懂不懂?”
(码农翻身注:详情参见《CPU阿甘》)
函数调用
C小伙看到不能难倒汇编老头儿,想到了自己可以定义函数,精神一振,问道:“函数调用你怎么处理啊?”
int funcA(int a){ ...... funcB(10) ...... } int funcB(int b){ ...... funcC(); ...... }
看看,这funcA调用funcB, funcB又调用funcC,函数嵌套调用,你那简单的指令能处理? C小伙儿心里暗想。
汇编老头儿不慌不忙:“你可算是问了一个有价值的问题,不过这也难不倒我,我需要内存配合一下就行了。”
“看到里边的栈帧没有,每个栈帧都表示一个函数的调用!”
“那这栈帧中有什么东西?” C小伙儿问道。
“细节太复杂,给你画个示意图看看吧!”
“不对啊,你这栈帧中有输入参数,有返回值,可是没有函数代码啊?代码去哪儿了?”
“真是幼稚! 这是运行时在内存中对函数的表达,那代码肯定是在代码段啊。” 汇编老头儿嘲讽道。
代码段的指令不断被CPU阿甘执行,遇到函数调用,就建立新的栈帧,函数调用结束,栈帧就会销毁,废弃。然后返回上一个栈帧。
C小伙儿意识到自己犯了一个大错误,他老是想着代码的静态结构,而忽略了运行时的表示。
编程语言的巅峰
他急于挽回面子,赶紧给C++打电话求援:“兄弟,快过来,治一下这个汇编老头儿!”
C++了解了事情的经过,说道:“兄弟,不行啊,别看我有class, 但是最终我也得变成过程化的程序,翻译成汇编,和你是一样一样的。”
(码农翻身注: 参见《面向对象圣经》)
“那 Python 呢, Java 呢?” C小伙儿有点气急败坏。
“他们更不行了,是虚拟机中的语言,他们连汇编老头儿的面儿都见不着,再说那虚拟机也是用你老兄C语言写的啊!”
C小伙呆住了,可不是,自己是很多系统级软件和编程语言的基础,已经非常贴近硬件了,自己治不了汇编老头儿,别人肯定也不行啊。
C小伙儿又想到了应用层那复杂的业务逻辑,他们都是由Python,Java, JavaScript等高级语言编写的,还用到了什么OOD,设计模式,函数式,响应式编程...... 但是它们都是一层层的抽象,帮助 程序员 更好地编写程序,在最底层,还是汇编啊。
他叹了一口气,对汇编老头说:“前辈,我服了,您可真是编程语言的巅峰啊。”
“不敢当,还有一个语言比我更厉害!”
“是谁?”
“机器语言! 只有0和1!不信你看看这程序员专属的键盘。”
你可能会喜欢:
以上所述就是小编给大家介绍的《编程语言的巅峰》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 码农翻身之编程语言的巅峰
- 最强编程语言 Java 和最受欢迎之 Python 的巅峰对决
- 团队建设活动:巅峰故事
- 巅峰极客第二场 WriteUp
- 【巅峰对决】MappedByteBuffer VS FileChannel
- 2020 开年,C 语言重回巅峰王座
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
现代前端技术解析
张成文 / 电子工业出版社 / 2017-4-1 / 79.00元
这是一本以现代前端技术思想与理论为主要内容的书。前端技术发展迅速,涉及的技术点很多,我们往往需要阅读很多书籍才能理解前端技术的知识体系。《现代前端技术解析》在前端知识体系上做了很好的总结和梳理,涵盖了现代前端技术绝大部分的知识内容,起到一个启蒙作用,能帮助读者快速把握前端技术的整个脉络,培养更完善的体系化思维,掌握更多灵活的前端代码架构方法,使读者获得成为高级前端工程师或架构师所必须具备的思维和能......一起来看看 《现代前端技术解析》 这本书的介绍吧!