【讨论】C++程序员是否该掌握某种汇编语言?
导语:日前网络上关于C++程序员是否应该对汇编语言有一定的掌握程度的问题讨论比较激烈。反对的观点大致有几点: 1.对于普通软件开发人员来讲,关注于上层实现,关注于功能和产品才是主要,汇编也用不到;2.很多的C++程序员不懂汇编,也成为了某公司某项目组主程序、核心研发,因此汇编可以不学不用;3.绝大多数C++程序员还是在做上层开发,绝大多数项目也是上层开发,不了解底层也能赚到大钱,而且是更多的钱;4.做底层,比如:逆向、破解、写病毒等,很多致力于这层的程序员,感觉整天昏天暗地,无数的重复劳动也没赚到大钱,觉得没意义;5.对于做C#、Java、WEB等领域的程序员们,大多数不会去关注底层实现,他们照样过得很好,以此类推,汇编也是可以不掌握的;6.汇编语言几乎是不跨平台的,于是就算掌握了某个平台的汇编,但在汇编语言上,例如语法、机制等还是有局限性。
本文作者作为一名C++程序员也参与了讨论。作为站在支持一方,他就上面几种反对的观点的看法(可以总体分为几个关键点:利益、收入和兴趣)以及个人的体会分享了看法,有一定参考价值。
以下是根据他的文章整理而成的内容:
从上面几种反对的观点来看,可以总体分为几个关键点:利益、收入和兴趣。我不打算将这三个关键点分别进行针对性阐述,因为它们之间都是息息相关分不开的。对于利益和收入上来讲,的确是有很多公司的高职位且收入不错的程序员并不了解汇编和底层,这样也不代表他们没有能力,而往往他们是非常有能力的人。这样一来似乎和我个人的支持类的观点有所冲突,但我认为这个冲突可以用追求二字来化解。为什么可以用追求来化解呢?因为追求可以是任何领域、任何方向、任何目的和任何标准的,因此也就是我前面所说的,归结到根本,掌握不掌握都没有对错。
我们进入这个行业,从事了编程工作(大多数程序员都是编程开发做起的)。我相信很多程序员的初衷,都是对编程开发有很大的兴趣,兴趣驱使着我们熬夜,驱使着我们研究, 驱使着我们进步。对于C++程序员,我相信兴趣占有很大的比重。那么,我们来举几个例子:
你应该看过《深入C++对象模型》这本书吧,这是一本非常细致和美妙的书,我想你应该有这样的感受。那么在此基础之上,你有过更多的思考吗?这本书里都是以实例和理论来进行讲解的,实例是以C++语言进行描述的。于是你是否有想知道在具体的编译器和平台下的这样一些疑问:
1.this指针是怎么传递进成员函数的?成员函数和普通函数以及静态成员函数有何区别和联系?
2.透过语法,成员函数和类在内存中有什么联系?对象和成员函数有何种联系?
3.函数间的调用原理,是怎么实现的?
4.__cdecl、__stdcall、__thiscall和__fastcall这几种函数调用方式,在本质上有什么区别?具体是怎么实现的?
5.虚函数、多态和继承在本质上的体现,以及这些机制在底层是怎么实现的?
除此之外,你在学习和使用C++的时候,我想你还会在乎一些细节,例如:
1).递归函数一定会导致低效?编译器针对递归函数会不会有什么样的优化?你怎么知道这些优化细节?
2).对于这句代码:int b = a > 0 ? 100 : 200; // int a; 编译器会有什么细节上的优化?这句代码会有比较并跳转的过程吗?
3).对于这样的代码:
view plaincopy to clipboardprint?
- #include <stdio.h>
- int a = 10;
- int main( void )
- {
- printf( "%d", a );
- return 0;
- }
在VC下,开启全局优化,全局变量a还存在吗?你怎么通过本质的论证来证明?
4).对于:float a = 100; int b = a / 30; 在VC下,你会不会怀疑这两句代码背后会存在函数调用?如果有,调用了什么函数?为什么?
5).对于__declspec( thread ) int g_nNum = 0; 你知道g_nNum++;这句代码背后的具体实现机制吗?
6).对于调试,你会怎么根据自己记录的程序崩溃时的堆栈现场及其它信息来错误跟踪查找呢?
7).对于开发游戏来说,你怎么知道外挂是怎么修改游戏程序的,修改了哪个地方呢?
8).你要怎么熟悉编译器的优化细节,怎么写出适应它的代码,怎么写出比它优化得更好的代码?
还有很多这样上层开发的例子,这里就不一一列举了。从上面列举的这些疑问,我想作为一名C++程序员,热爱编程开发的程序员来讲,你都想知道其中的原委。作为上层开发者,是应该关注上层的功能开发和产品方面的东西。但是我个人觉得,本着技术,本着这份热爱,本着自身的技术发展,了解更底层一些,有助于上层开发的通透性,以及全局的掌控力度。从我个人的感受来讲,当把握了关键细节以及全局设计之后,任何地方出了问题,都能很及时的反应并予以追查和处理。在当前的编译器技术上,已经非常强大了,很多细节可以放心的交给编译器来优化和处理。但是我想,编译器不是万能的,人才是最智能的。掌握不是必然,但掌握了会更好。
对于初学者乃至工作了一定时间的程序员,对于C++,很多处于C++语法的层面,在语法上的条条款款使用得得心应手,问其本质,可能就缺乏一二了。我个人的经历来看,在掌握语法之后,在向下关注一下语法背后的具体实现,会通透很多。你会在内存上、数据上和程序的各种底层运行机制上会有深刻的认识。这也就是为什么去海边玩儿,还要潜水去看看海底世界。错过了海底,你会失去很多精彩,而这些精彩我想也是作为程序员应有的追求之一。
对于Java、C#以及WEB类领域的程序员,我想汇编可能相对遥远一些。在这方面的关注也会相对少一些,但结合前面的观点,作为程序员这个角色,都是让自己的程序在机器上面跑起来,那么我想这之间的诸多底层的疑问可以作为程序员的一种兴趣来研究。目的也是为了让自己更通透,更熟悉自己的平台。我不知道怎么表达通透二字,就我个人的感受就是,能够从现象联系到本质实现,并且能够从本质实现勾勒出一幅很清晰生动的图像在脑子里,一切都一目了然尽收眼底。有点居高临下,望长城内外,惟余莽莽的那种宽广的感触。
对于本身就处于底层开发的程序员来说,无可厚非,掌握汇编就是必须的了。但是澄清一点,本文的观点更多的是从兴趣和通透性上出发,对于底层开发者可能会觉得底层有一定的枯燥,特别是整天破解、逆向等工作,非常多的体力活,从我几年的业余破解和逆向经验来看的确是这样的。但是我觉得,破解和逆向只是领域之一,我之所以破解和逆向,很多时候是处于兴趣和为了对上层进行更本质和合理的解释。所以,上层和底层结合,才是我的根本目的,也是本文想推崇的一种思路。
综上所述,我的观点是C++程序员乃至程序员,不管是作为兴趣还是工作,掌握或者了解一下汇编都是有一定必要的,但不是强制性的,也正所谓需求和追求不尽相同罢了。因此,不要问别人到底是否应该关注一下底层,掌握一下某种汇编语言,答案很明显。