Keil C51 Data Overlaying

Posted by: 邱小新 at 下午2:41 in

一般的編譯器將函數中的區域變數動態配置在 stack,等函數結束空間就釋放出來。因為 8051 的內部記憶體很少,只有區區 128 或 256 bytes,而且 stack 也是共用這塊記憶體。為了節省 stack 空間,所以區域變數基本上是靜態配置在固定位址, 也就是變成全域變數。如此就又造成浪費記憶體的情況,為了解決這個問題,所以 8051 的編譯器基本上都採用所謂的 data overlaying 技術來克服區域變數浪費空間的問題。

所謂 data overlaying 是指沒有呼叫關係的函數,它們的區域變數區可以重疊在一起(共用一塊記憶體)。Keil C51 會分析程式中函數間呼叫的關係,產生一個呼叫樹。它就根據這個呼叫樹來決定那些函數的區域變數區可以 overlaying 在一起。一種情況是是編譯器發現某一個函數(不是 main)沒有被別的函數呼叫,這會造成編譯器的困惑。一個正常的程式,除了 main 之外,除非是垃圾程式碼(沒用處但沒有刪除),否則所有的函數應該是至少會被一個其它函數呼叫的。編譯器在安全至上的原則下,會認定它的分析無法正確的辨識這個函數呼叫關係,所以對這個函數的區域變數就會獨立配置,不會重疊配置。這樣有沒有問題?邏輯上當然不會有問題,但沒 overlaying 就是會浪費記憶體,而且也會一直產生 *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS 的警告。

什麼情況下,函數的呼叫樹讓編譯器無法分析?真實應用是有一些情況會發生這樣的問題。最常見的就是使用函數指標來呼叫函數。因為呼叫是執行時期動態變動的,這就可以難倒編譯器了。在這種情況這些被呼叫的指標函數就會獨立配置它們的區域奱數。如果你要這些函數也能正確的使用 overlaying 的好處,那麼你就必需手動分析那些函數的呼叫樹,然後告訴編譯器就可以了。這樣你也就不會在編譯時產 UNCALLED SEGMENT 的警告了。

0 意見

張貼留言