新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 淺談51單片機(jī)內(nèi)存優(yōu)化

淺談51單片機(jī)內(nèi)存優(yōu)化

作者: 時(shí)間:2013-05-08 來(lái)源:網(wǎng)絡(luò) 收藏

對(duì) 51 單片機(jī)內(nèi)存的認(rèn)識(shí),很多人有誤解,最常見的是以下兩種:

① 超過(guò)變量128后必須使用compact模式編譯

實(shí)際的情況是只要內(nèi)存占用量不超過(guò) 256.0 就可以用 small 模式編譯

② 128以上的某些地址為特殊寄存器使用,不能給程序用

與 PC 機(jī)不同,51 單片機(jī)不使用線性編址,特殊寄存器與 RAM 使用重復(fù)的重復(fù)的地址。但訪問(wèn)時(shí)采用不同的指令,所以并不會(huì)占用 RAM 空間。

由于內(nèi)存比較小,一般要進(jìn)行,盡量提高內(nèi)存的使用效率。

以 Keil C 為例,small 模式下未指存儲(chǔ)類型的變量默認(rèn)為data型,即直接尋址,只能訪問(wèn)低 128 個(gè)字節(jié),但這 128 個(gè)字節(jié)也不是全為我們的程序所用,寄存器 R0-R7必須映射到低RAM,要占去 8 個(gè)字節(jié),如果使用寄存組切換,占用的更多。

所以可以使用 data 區(qū)最大為 120 字節(jié),超出 120 個(gè)字節(jié)則必須用 idata 顯式的指定為間接尋址,另外堆棧至少要占用一個(gè)字節(jié),所以極限情況下可以定義的變量可占 247 個(gè)字節(jié)。當(dāng)然,實(shí)際應(yīng)用中堆棧為一個(gè)字節(jié)肯定是不夠用的,但如果嵌套調(diào)用層數(shù)不深,有十幾個(gè)字節(jié)也夠有了。

為了驗(yàn)上面的觀點(diǎn),寫了個(gè)例子

#define LEN 120

data UCHAR tt1[LEN];

idata UCHAR tt2[127];

void main()

{

UCHAR i,j;

for(i = 0; i LEN; ++i )

{

j = i;

tt1[j] = 0x55;

}

}

可以計(jì)算 R0-7(8) + tt1(120) + tt2(127) + SP(1) 總共 256 個(gè)字節(jié)

keil 編譯的結(jié)果如下:

Program Size: data=256.0 xdata=0 code=30

creating hex file from "./Debug/Test"...

"./Debug/Test" - 0 Error(s), 0 Warning(s).

(測(cè)試環(huán)境為 XP + Keil C 7.5)

這段代碼已經(jīng)達(dá)到了內(nèi)存分配的極限,再定義任何全局變量或?qū)?shù)組加大,編譯都會(huì)報(bào)錯(cuò) 107

這里要引出一個(gè)問(wèn)題:為什么變量 i、j 不計(jì)算在內(nèi)?

這是因?yàn)?i、j 是局部變量,會(huì)試著將其優(yōu)化到寄存器 Rx 或棧。問(wèn)題也就在這了,如果局部變量過(guò)多或定義了局部數(shù)組,無(wú)法將其優(yōu)化,就必須使用 RAM 空間,雖然全局變量的分配經(jīng)過(guò)精心計(jì)算沒(méi)有超出使用范圍,仍會(huì)產(chǎn)生內(nèi)存溢出的錯(cuò)誤!

而編譯器是否能成功的優(yōu)化變量是根據(jù)代碼來(lái)的


上一頁(yè) 1 2 下一頁(yè)

評(píng)論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉