學習彙編語言有什麼好處?

想知道學習彙編對其他高層次的語言有什麼幫助,比如彙編對與深入理解java、objective-c的作用


學彙編不是說一定要用這玩藝做多牛鼻的事情, 問題的關鍵在於, 學透了彙編會使你真正理解計算機

另外一方面, 如上面所說, 在工作中你遲早會在某個陰暗的角落遇到彙編. 不管你承認不承認, 現在的CPU沒有直接跑高級語言的, 哪怕是虛擬機也都是類似彙編的指令集.
當遇到崩潰分析, 性能優化甚至編譯器抽風等等的時候, 彙編是你最後一根救命稻草.


在我將近10年的嵌入式編程的實踐過程中,真正使用彙編的地方並不多。尤其是ARM這樣使用地址空間操作寄存器的方式,大部分代碼都可以用C完成,彙編的技能主要用於:
1、閱讀bootloader代碼:基本上,除了OS的核心部分有彙編代碼以外,boot loader 的一部分一般是由彙編代碼完成,能讀懂這些代碼對體系架構的理解和設備啟動的流程都很有幫助。

2、分析問題:現在編譯器優化的很厲害,生成的代碼和C代碼有時很難又嚴格的對應,所以在單步跟蹤某些問題的時候,需要能夠看懂一些彙編語句來分析程序真正執行的流程。

3、性能:大部分時候編譯器的優化已經夠好,我們手寫的彙編的效率未必比他高,但是有些特定的場景,我們可以通過彙編調用CPU的專用硬體指令來進行優化。

我對我自己對彙編的要求就是能看懂和分析,不要求能夠編寫複雜的彙編程序。而且彙編大部分是相同的,掌握一種,另一種可以猜個十之八九。


滙編是一般程序員能為機器編程的底層語言(現代的CPU/GPU還會把指令再分解成微指令),所以學習滙編能讓程序員知道機器在軟體層面上的最底層操作。那麼,熟悉滙編後,可以更容易理解C/C++/OC這類語言如何在機器上執行。一些有經驗的程序員,看滙編時可以快速映射為C/C++代碼。這些經驗和知識有很多好處:

  1. 性能優化:在設計及編碼中能考慮到底層的執行方式,從而能編寫高性能的代碼。
  2. 深度調試:遇到一些崩潰或其他問題時,在沒有調試信息下也可以找到問題所在。有時候遇到編譯器本身的錯誤,單憑研究源代碼無發定位。
  3. 工具開發:可以實現AOT/JIT編譯、native調試器、內存/性能剖析工具等。

======================================================================
2014/3/21按評論補充

C/C++/OC雖然作為高級語言,其語言設計之所以是現在這樣的,當中考慮了很多機器相關的因素。這些語言和設計為運行於虛擬機器或託管環境的語言不一樣。

例如面向對象中的多態實現,C++的虛函數為什麼要標註virtual,而Java的非靜態、非final的方法就必然支持多態的?而OC的message dispatch會比虛函數慢么?它是怎麼實現的?

又例如,學習C++時,可能會問引用是怎麼實現的?如果只把它當作一個黑盒,就無法判定它相對於指針是否有額外的開銷。

最後再舉多一些C的例子吧,為什麼在C中讀寫數組不會檢查索引是否越界?這和C99中加入restrict關鍵字又有什麼關係?


我在另一個問題下的答案,轉移過來。

--------------------------------------------------------------------------------------------------------------

嵌入式電工來回一個吧。

當年學微機原理時,學過x86的彙編,考完試就全忘了;
學單片機時,學過8051的彙編,畢業兩年後就忘了;
ARM的彙編,v4和Thumb-2比較熟;
DSP的彙編,TI的C54xx比較熟。
其實所謂的全忘指的是指令集忘了,不同片子的彙編,規則還是一樣的。
比較熟是指熟到什麼地步呢。ARM——調試底層時,遇到奇怪的問題,打開Disassembly查看反彙編代碼,基本都能看得懂,偶爾會有幾個指令不認識,翻翻指令集就能看明白,但沒寫過;DSP——寫過幾個大量計算的函數,本來用C寫的,但發現太耗時間,就改用ASM,一邊翻指令集一邊寫。

以上算是背景介紹,現在回答問題,學習彙編有什麼意義?以下回答只針對嵌入式軟體,非嵌入式,不是不想回答,只是不懂,不敢亂答。
1、某些特殊環境,必須要用。比方說前幾年中穎的MCU就不支持C,幾年過去了,現在支不支持不清楚,不過即便8位機支持了,想必4位機還是不支持的。(這個幾年沒接觸了,不太了解,但這個是最剛性的一個理由。)
2、你說不支持C太low了。好吧,我們用支持C的,調試底層,會遇到一些奇怪的、無厘頭的問題,得打開反彙編窗口,看看硬體是怎麼執行的,必要時還要在彙編層面單步執行,一次只執行一條彙編指令。舉個例子,變數out映射到某個pin了,你要在這個pin上產生一個下降沿,你就寫了句out=1; out=0; 但是運行起來,卻只有低電平,沒有下降沿,why?看看彙編吧,out=1沒了!被編譯器優化掉了,根本沒執行。。。。好吧,我們加個volatile。
3、裸跑太不爽了。那行,我們移植個OS吧,複雜點就Linux,簡單點就μCos,彙編又跑出來了。。。。在執行main之前我們得分配好內存,安排好中斷向量表,放好heap和stack;進入main了,任務切換,要保存現場,要更新寄存器,還得靠彙編。
4、底層太麻煩了,我們直接搞應用層。OK,做個信號處理吧,AD採集了大量數據,要求差分,要算頻譜,要做濾波,計算量太大,用while用for都可以,但時間。。。。還是用彙編吧。當然,此處不僅僅是將C改成彙編,因為都用彙編了,而且只是一個單進程,純運算的函數,就不考慮可移植性了,我們可以將其他的優化都用上,比方以位移代乘除,以空間換時間,總之一切都是為了提高效率。據我本人經歷,最高的一次是將函數運行時間縮小了20倍。20倍什麼概念?要是不用優化,老老實實用C的話,按照摩爾定律十八個月翻一番,你得要六年才能增長16倍。。。。當然換個好的演算法更好,但你C用的演算法,ASM也能用啊,還是比你快。
5、好吧,最後不談實際應用。即便真不寫、不看彙編,彙編也是有用的,學彙編的過程就是理解計算機的過程。不告訴你CPU的控制流、數據流,學一堆寄存器、累加器的名詞有用么?用語言描述也可以,「將寄存器A出棧」,這不就是「POP A」嗎?只不過你自己typedef了一套漢語描述的、不完整的指令集罷了。
那學計算機原理有什麼用呢?還是跟上面回答一樣,一是底層,二是效率。比方說寫個bootloader,不考慮可移植性,啟動代碼有現成的,那用C寫也可以,但你起碼得明白啥叫中斷向量表,程序要怎麼跳轉吧。


@Skogkatt 說,你總會在一些陰暗的角落被迫閱讀彙編


當你遇到這個:

或者這個:

或者這個:

的時候就有用了。抄起 ollydbg 直接解決。


以前用fasm彙編做過些win32程序。
可以說,彙編語言很有其特殊性,高級語言的一些抽象的概念,都被歸一和具象化了,C語言的指針,在彙編的世界裡簡直不值一提,因為地址,對地址的引用再平常不過了。另一方面,內存,緩存,寄存器,CPU,又構成了一個奇妙的世界,它們屏息恭立,靜待主公的每一條喻令。
我不相信,一個人用純手工一條條指令去雕琢他的程序,用手指感受計算機的呼吸時會無動於衷。……


如果你不知道有什麼用,那對你就沒有任何用。


形象點來說,學習之前你是Mr Anderson,之後你是Neo。


實際中幾乎沒有直接用途,但這是你搞明白計算機理論結構的必要過程

彙編 I/II/III/IV
- 系統DEBUG技能+1/3/6/10
- 內存控制+1/3/5/8
- 程序優化+1/2/3/5
- 新語言學習+0/0/3/5
- 彙編IV附帶技能:使用命令行編寫出可執行程序

- 編譯原理·專家級 需要 彙編II 作為前置
- 系統代碼調試·大師級 需要 彙編III 作為前置
- 並發代碼·大師級 需要 彙編II 作為前置
- C語言·宗師級 需要 彙編IV作為前置


防止老年痴呆


不請自來,作為一個老工程師,在工作的過程中,大約以下幾個地方用到彙編:
一、boot loader。我第一次接觸彙編,當時要做一個國半的板的boot loader。我花了幾天去學linux的boot loader,最後成功移植到公司的板上。那激動,別提了。後面還做了一個16位色的啟動畫面,做一個進度條,當時覺得挺有成就感的。
二、從那以後,我有意識的經常去反彙編看看編譯出來的代碼。在我學習C++的時候,曾有的基礎讓我一下子理解了虛函數的本質。
三、做嵌入式開發的時候,在一些性能要求比較高的場合,常常是C和彙編混編的。即使不用混編,對彙編的深入理解,能讓你知道怎麼組織你的代碼,以得到效率和可讀性的平衡。
四、破解。破解是必須理解彙編的,在感興趣的時候,我們曾經通過掛鉤,將一個程序里未加密的數據給讀出來了。
五、這個屬於軼事了。在我剛參加工作那會,公司有款產品,一個terminal程序,居然全是彙編寫的,而且模塊化還非常好。據說有個大牛在封閉開發的時候閑極無聊,一晚上用彙編開發了個俄羅斯方塊自己玩。餘生也晚,對此等牛人只能膜拜…
嗯,就醬紫,很多年沒寫代碼了,基本忘光了,悲哀


彙編是一種一通百通的東西
可能你工作中用像你說的高級語言,永遠用不到彙編
但是彙編能讓你知其然知其所以然

就跟你學音標一樣,不會音標也不妨礙你說英語,但是可能沒那麼標準,也不知道為什麼會這麼發音,偶爾一天碰上陌生的單詞就跪了。


在某些情況下,你除了彙編沒有別的選擇——
CPU,時鐘,以及內存尚未初始化的時候……
當你需要切換CPU的工作模式的時候……
當你需要直接操作協處理器的時候……

好吧,對於許多人以上情況可能永遠也不會遇到——
實際上我也只在學習階段遇到過……


嵌入式領域
我認為通過學習彙編可以更深刻地了解硬體結構


可以加強你找不到女朋友一個人獨立生活的能力。


我知道個好處是用人單位說要:精通C、C++JAVA、彙編、android、.net、HTML...............,時候。你少了個被拒絕的理由。


軟體的逆向工程,計算機病毒,免殺,加密,脫殼,外掛。Rootkit,軟體調試,統統都跟彙編掛鉤,即使不會寫,也需要能讀懂。


彙編和JAVA這種高級語言之間的差別實在是太大,直接影響應該是沒有。
如果是C的話,還能對應起來。
看過很多人說過,學習彙編最大的好處就是理解機器的執行過程,從自身的經驗來說,確實是這樣。用彙編寫一個鏈表結構,很容易就能理解C里的鏈表是怎麼工作的了,尤其是對於指針的理解會更深刻。


你逛知乎的時候,能看懂某些你以前不明覺厲的梗。


推薦閱讀:

以英語為母語的人寫代碼時是什麼感覺?
為什麼蘋果新語言 Swift 的 RC4 運算效能是 Python 的 220 倍?

TAG:編程語言 | 彙編語言 |