一般的編譯器將函數中的區域變數動態配置在 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 的警告了。