高级语言写代码时就能够想到对应的汇编代码是怎样一种体验?

关注者
650
被浏览
11205
从事编译器工作的话能做到“高级语言写代码时就能够想到对应的汇编代码”是颇为平常的事吧。术业专攻。
相信很多同行对自己维护的编译器都能做到这点,并不是什么“很厉害”的事情,实用倒是挺实用的。毕竟,连编译器的开发者都摸不清自己的编译器生成的代码长啥样的话,那还能指望用户用得放心么。
当然,专门做逆向工程的人也会因为需要而能熟练做到这点。不然像heap spray之类这么好玩的东西谁来弄 >_<

我写Java的时候,从Java源码到字节码,我人肉编译的结果可以跟javac生成的完全一致。这样我在写特定的测试时可以写Java代码就能构造出我需要的字节码,而很少要直接手写字节码(偶尔还是要的…)。Java源码与字节码之间的双向映射颇为直观,有兴趣可跳传送门:如何理解ByteCode、IL、汇编等底层语言与上层语言的对应关系? - RednaxelaFX 的回答
然后从字节码到机器码,我就会预期着我参与维护的JIT编译器会生成出怎样的代码模式,然后在检查实际生成的代码时如果跟我预期的不同,我就得去看看哪里出错了,或者说是不是有啥优化漏了没做嗯。

同时,从我们的JIT编译器生成的机器码反推出源码也是我经常要做的事情。经常要解些客户遇到的bug,手上就只有一个core dump file / bundle,其它啥都没了,客户也不会共享源码给我们,那就只能人肉从生成的机器码来分析出程序原本应该在做什么,而哪里看起来出错了。

对别的编译器我当然做不到对自己维护的编译器那么熟悉,不过有些东西还是有规可循的。

例如这样:Visual C++ 6以debug模式编译很拙笨,为何要做无用功? - RednaxelaFX 的回答
或者这样:提出结论,给出论据(二) <- 嗯看C#我也是能大致估摸出会得到怎样的机器码的。不然怎么玩这种把戏:要让CLR挂掉的话(第二弹)……
是的我没有抛弃微软 >_<

然后像脚本语言之类的,要在心中对执行了怎样的机器码有数当然也是做得到的。
例如之前玩Ruby的时候:
beef - Script Ahead, Code Behind
在Windows上使用Wilson

有别的回答提到CSAPP。正确阅读了它的话确实应该能掌握不少基础知识,例如这样:编译器生成的汇编语句执行顺序为什么与C代码顺序不同? - RednaxelaFX 的回答