點(diǎn)擊上方「嵌入式大雜燴」,選擇「置頂公眾號」第一時(shí)間查看嵌入式筆記!

來源:https://www.zhihu.com/question/23088538
在我將近10年的嵌入式編程的實(shí)踐過程中,真正使用匯編的地方并不多。
尤其是ARM這樣使用地址空間操作寄存器的方式,大部分代碼都可以用C完成,匯編的技能主要用于:
1、閱讀bootloader代碼:基本上,除了OS的核心部分有匯編代碼以外,boot loader 的一部分一般是由匯編代碼完成,能讀懂這些代碼對體系架構(gòu)的理解和設(shè)備啟動(dòng)的流程都很有幫助。
2、分析問題:現(xiàn)在編譯器優(yōu)化的很厲害,生成的代碼和C代碼有時(shí)很難又嚴(yán)格的對應(yīng),所以在單步跟蹤某些問題的時(shí)候,需要能夠看懂一些匯編語句來分析程序真正執(zhí)行的流程。
3、性能:大部分時(shí)候編譯器的優(yōu)化已經(jīng)夠好,我們手寫的匯編的效率未必比他高,但是有些特定的場景,我們可以通過匯編調(diào)用CPU的專用硬件指令來進(jìn)行優(yōu)化。
我對我自己對匯編的要求就是能看懂和分析,不要求能夠編寫復(fù)雜的匯編程序。而且匯編大部分是相同的,掌握一種,另一種可以猜個(gè)十之八九。
當(dāng)年學(xué)微機(jī)原理時(shí),學(xué)過x86的匯編,考完試就全忘了;
學(xué)單片機(jī)時(shí),學(xué)過8051的匯編,畢業(yè)兩年后就忘了;
ARM的匯編,v4和Thumb-2比較熟;
DSP的匯編,TI的C54xx比較熟。
其實(shí)所謂的全忘指的是指令集忘了,不同片子的匯編,規(guī)則還是一樣的。
比較熟是指熟到什么地步呢。ARM——調(diào)試底層時(shí),遇到奇怪的問題,打開Disassembly查看反匯編代碼,基本都能看得懂,偶爾會(huì)有幾個(gè)指令不認(rèn)識(shí),翻翻指令集就能看明白,但沒寫過。
DSP——寫過幾個(gè)大量計(jì)算的函數(shù),本來用C寫的,但發(fā)現(xiàn)太耗時(shí)間,就改用ASM,一邊翻指令集一邊寫。
以上算是背景介紹,現(xiàn)在回答問題,學(xué)習(xí)匯編有什么意義?
以下回答只針對嵌入式軟件,非嵌入式,不是不想回答,只是不懂,不敢亂答。
1、某些特殊環(huán)境,必須要用。比方說前幾年中穎的MCU就不支持C,幾年過去了,現(xiàn)在支不支持不清楚,不過即便8位機(jī)支持了,想必4位機(jī)還是不支持的。(這個(gè)幾年沒接觸了,不太了解,但這個(gè)是最剛性的一個(gè)理由。)
2、你說不支持C太low了。好吧,我們用支持C的,調(diào)試底層,會(huì)遇到一些奇怪的、無厘頭的問題,得打開反匯編窗口,看看硬件是怎么執(zhí)行的,必要時(shí)還要在匯編層面單步執(zhí)行,一次只執(zhí)行一條匯編指令。
舉個(gè)例子,變量out映射到某個(gè)pin了,你要在這個(gè)pin上產(chǎn)生一個(gè)下降沿,你就寫了句out=1; out=0; 但是運(yùn)行起來,卻只有低電平,沒有下降沿,why?看看匯編吧,out=1沒了!被編譯器優(yōu)化掉了,根本沒執(zhí)行。。。。好吧,我們加個(gè)volatile。
3、裸跑太不爽了。那行,我們移植個(gè)OS吧,復(fù)雜點(diǎn)就Linux,簡單點(diǎn)就μCos,匯編又跑出來了。。。。在執(zhí)行main之前我們得分配好內(nèi)存,安排好中斷向量表,放好heap和stack;進(jìn)入main了,任務(wù)切換,要保存現(xiàn)場,要更新寄存器,還得靠匯編。
4、底層太麻煩了,我們直接搞應(yīng)用層。OK,做個(gè)信號處理吧,AD采集了大量數(shù)據(jù),要求差分,要算頻譜,要做濾波,計(jì)算量太大,用while用for都可以,但時(shí)間。。。。還是用匯編吧。
當(dāng)然,此處不僅僅是將C改成匯編,因?yàn)槎加脜R編了,而且只是一個(gè)單進(jìn)程,純運(yùn)算的函數(shù),就不考慮可移植性了,我們可以將其他的優(yōu)化都用上,比方以位移代乘除,以空間換時(shí)間,總之一切都是為了提高效率。
據(jù)我本人經(jīng)歷,最高的一次是將函數(shù)運(yùn)行時(shí)間縮小了20倍。20倍什么概念?要是不用優(yōu)化,老老實(shí)實(shí)用C的話,按照摩爾定律十八個(gè)月翻一番,你得要六年才能增長16倍。。。。當(dāng)然換個(gè)好的算法更好,但你C用的算法,ASM也能用啊,還是比你快。
5、好吧,最后不談實(shí)際應(yīng)用。即便真不寫、不看匯編,匯編也是有用的,學(xué)匯編的過程就是理解計(jì)算機(jī)的過程。不告訴你CPU的控制流、數(shù)據(jù)流,學(xué)一堆寄存器、累加器的名詞有用么?
用語言描述也可以,“將寄存器A出棧”,這不就是“POP A”嗎?只不過你自己typedef了一套漢語描述的、不完整的指令集罷了。
那學(xué)計(jì)算機(jī)原理有什么用呢?還是跟上面回答一樣,一是底層,二是效率。比方說寫個(gè)bootloader,不考慮可移植性,啟動(dòng)代碼有現(xiàn)成的,那用C寫也可以,但你起碼得明白啥叫中斷向量表,程序要怎么跳轉(zhuǎn)吧。
由于微信公眾號近期改變了推送規(guī)則,如果您想經(jīng)常看到我們的文章,可以在每次閱讀后,在頁面下方點(diǎn)一個(gè)「贊」或「在看」,這樣每次推送的文章才會(huì)第一時(shí)間出現(xiàn)在您的訂閱列表里。
版權(quán)聲明:本文來源網(wǎng)絡(luò),免費(fèi)傳達(dá)知識(shí),版權(quán)歸原作者所有。如涉及作品版權(quán)問題,請聯(lián)系我進(jìn)行刪除。
猜你喜歡:
嵌入式大雜燴文章精選
手把手教你使用VSCode + gdb + gdbserver調(diào)試ARM程序
國產(chǎn)良心工具——FinalShell
分享10道有趣的C語言面試題及答案
一次關(guān)于WiFi 驅(qū)動(dòng)移植的總結(jié)復(fù)盤
在公眾號聊天界面回復(fù)1024,可獲取嵌入式資源;回復(fù) m ,可查看文章匯總。
文章都看完了
不點(diǎn)個(gè)
嗎