当前位置: 首页 > 科技观察

编程语言的巅峰

时间:2023-03-20 10:48:36 科技观察

“哇,怎么会这么简单!”C语言老人还是个年轻人的时候,第一次见到汇编,发出这样的感叹。从C语言的角度看,这个汇编的指令太简单了,简单到只有几种指令:数据传输:将数据从一个位置复制到另一个位置,比如从内存到寄存器,或者从寄存器到内存,或从寄存器到寄存器。算术逻辑运算:无非是加减乘除、与、或、左移、右移控制类:比较两个值,跳转到某个位置。老装配工很得意。他经常嚣张地说:“别看我的指令那么简单,但是有我的寄存器和内存,就可以完成你们所谓的高级语言的所有功能了!”这个寄存器是什么鬼?C语言脑子里只有内存和指针,完全没有寄存器的概念。其实这是属于CPU阿甘正传的容量有限但速度超快的存储单元。32位CPU寄存器图片来源:http://pascalturbo.net/cpu-registers/ArrayC看着瘦瘦的汇编体,想到了我优雅的if,beautifulwhile,for,极其重要的函数调用,我不由在心里嘀咕:我的程序怎么会编译成这么简单的汇编呢?虽然有些不屑,但那位C佬还是很恭敬的:“前辈,我这边有个数组的概念,编译成汇编是什么样子的?”整数[10];数[0]=100;数[1]=200;除了机器语言,它是最古老的汇编语言,甚至C语言最早的编译器都是用汇编语言编写的,当之无愧的前辈。老汇编没想到C佬连这道题都不懂,说:“我这里只认寄存器和内存,你所谓的数组就是一段连续的内存空间,我只需要知道开头地址。”C哥看到了,好家伙,他连num这个变量名都不需要。不过确实如此,汇编老头只要记住起始地址,顺着地址就能找到所有东西。“咦,这个0x000083d0不就相当于我的指针吗?”“是的,但是在这里,都是地址,别提指针了!”如何处理?if(x=y,跳转到.L1执行subl%edx,%eax;计算y-x,将结果保存在eax寄存器中jmp.done;跳转到.done标签。L1:subl%eax,%edx;计算x-ymovl%edx,%eax;将结果保存在eax寄存器中。完成:;计算完成,结果保存在eax寄存器中(码农注:本例来自《深入理解计算机系统》)看了半天,C小伙终于明白了这段汇编程序的意思。所谓jge就是进行判断,然后跳转到特定的位置去执行,就像if和goto的结合。老汇编见C小子听懂了,问道:“你想想你的while循环和for循环,是不是只是if和goto的包装?”C小伙想了想:“确实是这样!”“到此结束,我的程序集看起来很简单,但是它可以表达你所有的流控语句,不管ifelse,while,for,switch,对不对?”C小伙觉得汇编里老哥说的是谬论:“这个goto很简单,但是程序读起来很复杂!”老汇编说:“你说到点子上了,所谓高级语言主要是为了方便人类的书写和阅读,是为了提高人类的效率。在我的例子中,它主要由CPUForrestGump执行。那个傻孩子速度很快,什么都不懂。你只需要告诉它指令,越简单越好。不料,CPU阿甘听到了嘲讽,不满地说:“老头子,你在背后说我坏话,执行了亿万条指令,我已经领悟到程序的局部性原理了,明白了吗?”“(码农注:详见《CPU阿甘》)函数调用C小伙一看打不过汇编老头,以为自己可以定义函数了,神清气爽,问:“你怎么弄的?”调用函数?处理它?”intfuncA(inta){...funcB(10)...}intfuncB(intb){...funcC();...}你看,这个funcA调用funcB,funcB调用funcC,函数嵌套调用,你能简单点吗说明书处理了吗?C哥心里想着。老汇编淡定地说:“你也算是问了一个有价值的问题,不过我不介意,我只是需要内存配合。”“看看里面有没有栈帧,每个栈帧代表一个函数称呼!”“那这个栈帧里有什么?”C问。“细节太复杂了,我画个示意图给你看!”“没有,你这个栈帧里面有输入参数和返回值,但是没有函数代码?代码跑哪去了?”“太天真了!这就是函数在运行时在内存中的表达式,那么代码一定是在代码段。老汇编器嘲讽道。代码段中的指令被CPU阿甘正传不断执行。当一个函数调用是遇到,创建一个新的栈帧,当函数调用结束时,这个栈帧会被销毁并丢弃。然后返回到之前的栈帧。C小伙意识到自己犯了一个大错误。他总是想着static编程语言的黑客急于挽回代码结构并忽略运行时表示。编程语言的黑客急于呼叫C++求助:“兄弟,过来,修复这个编译老头!”C++明白发生了什么,并说:“大哥,不行,虽然我有类,但是最后我得变成程序化的程序,翻译成汇编,你也一样。”(码农注:见《面向对象圣经》)“Python呢,Java呢?”C小伙有些郁闷。“更惨的是他们,是虚拟机里面的语言,他们连组装的老头都见不着,况且虚拟机也是你哥的C语言写的!”C小伙惊呆了,不对,他自己就是很多系统级软件和编程语言的基础。已经很接近硬件了。修不了编译的老头,肯定是别人修不了的。C小伙想到了应用层复杂的业务逻辑。它们都是用Python、Java、JavaScript等高级语言编写的。用的什么OOD、设计模式、函数式、响应式编程……不过都是一层一层的抽象,帮助程序员更好的写程序。在最高层次上,它仍然是组装。他叹了口气,对老汇编器说道:“前辈,我服了,您真是编程语言的高手。”“我不敢,还有比我更好的语言!”“是谁?”“机器语言!只有0和1!不信你看看这个程序员的专属键盘。”