Keil C51 Data Overlaying
一般的編譯器將函數(shù)中的區(qū)域變數(shù)動態(tài)配置在stack,等函數(shù)結(jié)束空間就釋放出來。因為8051 的內(nèi)部記憶體很少,只有區(qū)區(qū)128 或256 bytes,而且stack 也是共用這塊記憶體。為了節(jié)省stack 空間,所以區(qū)域變數(shù)基本上是靜態(tài)配置在固定位址,也就是變成全域變數(shù)。如此就又造成浪費記憶體的情況,為了解決這個問題,所以8051 的編譯器基本上都采用所謂的data overlaying 技術(shù)來克服區(qū)域變數(shù)浪費空間的問題。
所謂data overlaying 是指沒有呼叫關(guān)系的函數(shù),它們的區(qū)域變數(shù)區(qū)可以重疊在一起(共用一塊記憶體)。Keil C51 會分析程式中函數(shù)間呼叫的關(guān)系,產(chǎn)生一個呼叫樹。它就根據(jù)這個呼叫樹來決定那些函數(shù)的區(qū)域變數(shù)區(qū)可以overlaying 在一起。一種情況是是編譯器發(fā)現(xiàn)某一個函數(shù)(不是main)沒有被別的函數(shù)呼叫,這會造成編譯器的困惑。一個正常的程式,除了main 之外,除非是垃圾程式碼(沒用處但沒有刪除),否則所有的函數(shù)應(yīng)該是至少會被一個其它函數(shù)呼叫的。編譯器在安全至上的原則下,會認定它的分析無法正確的辨識這個函數(shù)呼叫關(guān)系,所以對這個函數(shù)的區(qū)域變數(shù)就會獨立配置,不會重疊配置。這樣有沒有問題?邏輯上當(dāng)然不會有問題,但沒overlaying 就是會浪費記憶體,而且也會一直產(chǎn)生*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS的警告。
什么情況下,函數(shù)的呼叫樹讓編譯器無法分析?真實應(yīng)用是有一些情況會發(fā)生這樣的問題。最常見的就是使用函數(shù)指標來呼叫函數(shù)。因為呼叫是執(zhí)行時期動態(tài)變動的,這就可以難倒編譯器了。在這種情況這些被呼叫的指標函數(shù)就會獨立配置它們的區(qū)域奱數(shù)。如果你要這些函數(shù)也能正確的使用overlaying 的好處,那么你就必需手動分析那些函數(shù)的呼叫樹,然后告訴編譯器就可以了。這樣你也就不會在編譯時產(chǎn)UNCALLED SEGMENT 的警告了。