一些c51編程技巧及原理
c51 的編譯模式
- small 所有未明確說明存儲區域的變量和重入堆棧默認保存在data區,總容量爲128B。
- compact 所有未明確說明存儲區域的變量和重入堆棧默認保存在pdata區,總容量爲256B。
large 所有未明確說明存儲區域的變量和重入堆棧默認保存在xdata區,總容量爲64KB。
片內存儲區尋址空間
- data 片內RAM的00-7FH
- idata 片內RAM的00-FFH
- bdata 片內RAM的20-2FH
- 片外存儲區尋址空間
- pdata 片外RAM中的某一頁(256B)
- xdata 整個片外RAM 0000H-FFFFH
棧
- 硬堆棧:由SP指針和PUSH/POP指令支持的系統堆棧,位於data區,由低向高地址生長。在編譯器對全部data變量完成分配之後,緊接着安排的是硬堆棧
- 壓縮棧:函數參數,局部變量;由編譯器分配的固定存儲位置
- 模擬棧:“可重入棧”,專門爲可重入函數開闢的模擬堆棧,目的是安排可重入函數中的字節型參數和字節型局部變量
可重入
在標準C中,函數默認是可重入的,這是因爲它的堆棧空間很大。51單片機的理論堆棧空間最大不超過128B/256B。在C51中,函數參數和函數中的局部變量除了一部分用寄存器來傳遞或分配在寄存中外,其他都是保存在編譯器所分配的固定地址(壓縮棧??),所以C51默認是不可重入的。可重入函數需顯示聲明。
同理,不可遞歸。
keil中函數指針
編譯器無法判斷函數的調用。因爲ram分配採用overlay方法,若指針在中斷或遞歸調用中會發生問題。
解決:
- 函數指針指向函數不使用內存,僅用寄存器
- 使用reentrant關鍵字修飾函數,並在startup.a51中初始化可重入棧
- 通知linker實際的調用關係