首先說(shuō)一下 MCU 的存儲(chǔ)器組織。
蒙圈,MCU 中常使用的存儲(chǔ)器類(lèi)型有:FLASH、RAM、ROM(包括EEPROM)
在軟件角度來(lái)看,程序和數(shù)據(jù)的存儲(chǔ)分為以下幾個(gè)部分:
注:
1.代碼段和常量段都可以用于保存常量數(shù)據(jù),其主要區(qū)別是,如果常量可以作為匯編指令的一個(gè)操作數(shù),則該常量被編譯進(jìn)代碼段。如果不能用一個(gè)匯編操作數(shù)表示,則存于常量段。如 "uchar a=0x05;" 中的 "0x05" 將被編譯成代碼 "mov #0x05, a";如果是 "uchar a[]={0x05, 0x06}" 則 "0x05,0x06" 被放置于常量段, 在初始化 a[] 的時(shí)候會(huì)有一段匯編指令用于將常量段中的內(nèi)容拷貝到 a[] 中。
軟件存儲(chǔ)區(qū)與硬件存儲(chǔ)器類(lèi)型是怎么對(duì)應(yīng)的呢?
一般來(lái)講如下:
注:
1.MCU 中的 ROM 通常用于存儲(chǔ)制造商信息、控制器型號(hào)等信息;
2.對(duì)于 x86 體系結(jié)構(gòu)的系統(tǒng),因?yàn)闆](méi)有 Flash 類(lèi)型的存儲(chǔ)器,所以,所有的軟件存儲(chǔ)區(qū)最終都加載到內(nèi)存中,但是其內(nèi)存是分段的,用戶對(duì)不同內(nèi)存段的訪問(wèn)權(quán)限不同,其代碼段和常量段不可以被用戶修改,如果意外修改則拋出段錯(cuò)誤異常。
知道了存儲(chǔ)器類(lèi)型和各存儲(chǔ)區(qū)的劃分之后,讓我們來(lái)看以下三組程序:
1.
staticvoidProcStr(void)
{
ucharStr[]={"12345"};
}
這段程序中,Str[] 是一個(gè)局部數(shù)組,其大小為 6,占用的堆棧空間是 2 個(gè)字符;"12345" 是常量,被存儲(chǔ)在常量段;Str[] 的初始化過(guò)程,相當(dāng)于從常量區(qū)拷貝 6 個(gè)字符的數(shù)據(jù)到棧中,這 6 個(gè)字符是"12345\0"。
2.
staticvoidProcStr(void)
{
ucharStr[]="12345";
}
這段程序中,Str[] 是一個(gè)局部數(shù)組,其大小為 6,占用的堆??臻g是 2 個(gè)字符;"12345" 是常量,被存儲(chǔ)在常量段;Str[] 的初始化過(guò)程,相當(dāng)于從常量區(qū)拷貝 6 個(gè)字符的數(shù)據(jù)到棧中,這 6 個(gè)字符是 "12345\0"。
3.
staticvoidProcStr(void)
{
constuchar*Str="12345";
}
這段程序中沒(méi)有數(shù)組,唯一的Str 是一個(gè)局部指針,其大小為 4(在 32 位系統(tǒng)中),因此這段程序只占用 4(在 32 位系統(tǒng)中)個(gè)字符的堆棧空間;"12345"是常量,被存儲(chǔ)在常量段;Str 的初始化過(guò)程,是將指針Str 初始化為常量"12345"的地址,后續(xù)程序通過(guò)指針Str直接訪問(wèn)常量段,無(wú)需內(nèi)存拷貝過(guò)程。
從以上分析可以看出,前兩種方法是一樣的,都需要為局部數(shù)據(jù)分配存儲(chǔ)空間,并將靜態(tài)存儲(chǔ)區(qū)的數(shù)據(jù)拷貝過(guò)來(lái),而最后一種方法是通過(guò)指針直接訪問(wèn)靜態(tài)數(shù)據(jù)而無(wú)需拷貝。如果字符串長(zhǎng)度大于系統(tǒng)中指針的長(zhǎng)度,第三種方法將在時(shí)間和空間上大大優(yōu)于前兩種方法(第三種方法極大的節(jié)省了堆棧空間,并減少了拷貝數(shù)據(jù)所用的時(shí)間)。
但是,對(duì)于 MCU 來(lái)說(shuō),并不總是第三種方法好,原因在于第三種方法是直接訪問(wèn)常量段,由上面的表可知,對(duì)于將常量存儲(chǔ)于 Flash 的 MCU 來(lái)說(shuō),訪問(wèn)常量段要比訪問(wèn) RAM 慢得多。因此,如果接下來(lái)要頻繁訪問(wèn)這個(gè)字符串,那么,采用前兩種方法在速度上將會(huì)更優(yōu)一些,理由是前兩種方法只需要訪問(wèn)一次 Flash,而第三種方法則每次都需要訪問(wèn) Flash。
當(dāng)然,如果在接下來(lái)的程序中,需要修改字符串Str 中的內(nèi)容,那就只能采用前兩種方法,第三種方法將會(huì)提示錯(cuò)誤。
特殊說(shuō)明:今天講的一些內(nèi)容跟編譯器的特性相關(guān),不同編譯器,甚至相同編譯器的不同版本間存在一定差異。
-
mcu
+關(guān)注
關(guān)注
146文章
17204瀏覽量
351935 -
存儲(chǔ)器
+關(guān)注
關(guān)注
38文章
7519瀏覽量
164084 -
編譯器
+關(guān)注
關(guān)注
1文章
1639瀏覽量
49198
原文標(biāo)題:嵌入式程序開(kāi)發(fā)需要知道的存儲(chǔ)器知識(shí)
文章出處:【微信號(hào):gh_c472c2199c88,微信公眾號(hào):嵌入式微處理器】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論