在嵌入式系統(tǒng)中,對內(nèi)存地址的操作是一個重要的方面,從廣義上講,嵌入式系統(tǒng)的地址空間可以分成以下三種類型:
系統(tǒng)的內(nèi)存
處理器外部部件的內(nèi)存映射
無論哪種內(nèi)存,一般都映射到處理器的內(nèi)存空間中。在x86系統(tǒng)中,分為內(nèi)存和I/O映射兩種內(nèi)存;在ARM體系中,全部的地址都在32位的內(nèi)存空間中,所有的操作都是對32位地址空間內(nèi)存的操作。
從編程的角度看,嵌入式系統(tǒng)和PC系統(tǒng)的軟件設(shè)計的一個重要的區(qū)別即在于嵌入式系統(tǒng)更重視對硬件的操作。而對硬件的操作需要通過操作內(nèi)部寄存器和外圍部件內(nèi)存映射的地址實現(xiàn),其實現(xiàn)方式都是通過對內(nèi)存讀、寫兩種操作。
在匯編語言中,各種處理器都有對內(nèi)存的不同的尋址方式讀寫內(nèi)存。在高級語言中,C語言是唯一可以進(jìn)行內(nèi)存操作的語言,C語言對內(nèi)存的操作主要需要通過指針來完成。
1、使用指針操作內(nèi)存
在C語言中,指針是一種非常重要的數(shù)據(jù)類型。使用指針變量可以表示各種數(shù)據(jù)結(jié)構(gòu),能很方便地使用數(shù)組和字符串,并能像匯編一樣處理內(nèi)存地址。指針的本質(zhì)就是一個地址,在32位的系統(tǒng)中,指針是一個32位的無符號整數(shù)。指針可以用一個變量來表示,變量的指針實際上就是變量的地址。存放變量地址的變量是指針變量。一個指針變量的值就是某個變量的地址或稱為某變量的指針。
一個簡單的指針應(yīng)用如下所示:
int a;
int *p = &a;
這個例子表示,整型指針型變量p指向a的地址,此時對*p的操作等同于對a的操作。
使用指針可以指向一個變量,也可以指向一個由malloc函數(shù)分配的內(nèi)存,例如:
void *p = malloc(1024);
系統(tǒng)分配1024字節(jié)的內(nèi)存,然后讓變量p指向這塊內(nèi)存,即p的值是這1024字節(jié)的連續(xù)內(nèi)存的地址。在程序中就可以通過p來操作這塊內(nèi)存區(qū)域。在內(nèi)存使用完成后,需要使用free函數(shù)講內(nèi)存釋放。
free(p);
在嵌入式系統(tǒng)中的程序開發(fā)中,指針的值除了以上的兩種形式(從系統(tǒng)內(nèi)存分配或者指向變量)以外,還可以使用絕對的數(shù)值。這是由于在嵌入式系統(tǒng)中,外設(shè)寄存器和外部部件的內(nèi)存映射的地址空間可能都是固定的,因此可以使用指針來處理他們。
例如,如果需要在地址0x0040處寫入一個字節(jié)的數(shù)據(jù)0xf0,可以使用如下的程序:
unsigned char *p = (unsigned char *)0x0040;
*p = 0xf0;
這個程序定義了一個指向0x0040地址的字節(jié)型的指針,然后向該地址寫入數(shù)據(jù)0xf0。
上面的程序等同于:
*(unsigned char *)0x0040 = 0xf0;
所以說不使用指針變量也可以對實際的地址操作。讀內(nèi)存的程序與之類似,可以使用指針變量或者直接使用地址得到內(nèi)存中的數(shù)據(jù)。
2、指針的類型
前面的程序在內(nèi)存的一個指定的地址處寫入一個字節(jié)(8位)的數(shù)據(jù)。如果需要寫入兩個字節(jié)(16位)的數(shù)據(jù),需要改變指針類型。例如:同樣向地址0x0040處寫入兩個字節(jié)的數(shù)據(jù)0x0f0f,需要使用如下的語句:
*(unsigned short*)0x0040 = 0x0f0f;
在這個語句中,使用unsigned short而不使用unsigned char,short在C語言中代表16位的整數(shù)。
如果寫入4個字節(jié)(32位)的數(shù)據(jù),則需要使用一下的程序:
*(unsigned long*)0x0040 = 0xf0f0f0f0;
在這個語句中,使用unsigned long,long在C語言中代表32位的整數(shù)。
在32位的系統(tǒng)中,一般編譯器認(rèn)為int代表是32位的整數(shù),等同于long,所以習(xí)慣使用int代替long作為內(nèi)存操作的數(shù)據(jù)類型。
注意:指針的類型決定了使用指針進(jìn)行讀寫操作時每次讀寫字節(jié)的數(shù)目。
3、指針的增量
在對指針變量的操作中,有時需要對指針變量進(jìn)行加減運算。例如:
unsigned char *p = (unsigned char *)0x0040;
P++;
*p = 0xf0;
這段程序的含義是向地址0x0041的字節(jié)處寫入數(shù)據(jù)0xf0。
指針加減運算的含義是:指針的單位增量(或減量)等于指針類型所占的內(nèi)存量。
對指針進(jìn)行增量操作的使用,增加的單位是以指針類型的大小:char類型的增量表示增加1字節(jié)的內(nèi)存,short表示增加2字節(jié)的內(nèi)存,long和int表示增加4字節(jié)的內(nèi)存,這些工作是編譯器根據(jù)指針的類型自動完成的。
總結(jié):對指針進(jìn)行加減運算的時候,它的變化量與指針的類型有關(guān)。
4、指針的類型轉(zhuǎn)換
在C語言中,指針的類型可以在使用的時候進(jìn)行轉(zhuǎn)換。指針的本質(zhì)是一個地址,在32位系統(tǒng)中,指針就是一個32位無符號的整數(shù)。因此,各種指針都可以相互轉(zhuǎn)化,而且指針在轉(zhuǎn)換過程并沒有任何實質(zhì)性的變化,只是告訴編譯器,目前的指針指向何種的內(nèi)存區(qū)域。
在嵌入式系統(tǒng)中,處理器的片內(nèi)設(shè)備一般都會映射到處理器的地址空間中。這些寄存器有可能是32位的,有可能只有8位,這時就需要使用C語言中不同類型的指針。
總結(jié):指針的本質(zhì)是一個無符號的整數(shù),各個類型的指針都可以進(jìn)行相互轉(zhuǎn)換。
責(zé)任編輯:haq
-
處理器
+關(guān)注
關(guān)注
68文章
19440瀏覽量
231321 -
嵌入式
+關(guān)注
關(guān)注
5096文章
19189瀏覽量
308028 -
內(nèi)存
+關(guān)注
關(guān)注
8文章
3064瀏覽量
74383
原文標(biāo)題:聊一聊內(nèi)存指針操作
文章出處:【微信號:CanaanTech,微信公眾號:嘉楠科技】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
嵌入式主板的概述與發(fā)展
![<b class='flag-5'>嵌入式</b>主板的概述與發(fā)展](https://file1.elecfans.com/web2/M00/EB/A1/wKgZomZe5fWAXs4EAABHp9zbA6E074.png)
新手怎么學(xué)嵌入式?
嵌入式系統(tǒng)開發(fā)與硬件的關(guān)系 嵌入式系統(tǒng)開發(fā)常見問題解決
什么是嵌入式操作系統(tǒng)?
嵌入式 Linux 操作系統(tǒng)配置
嵌入式系統(tǒng)的未來趨勢有哪些?
嵌入式linux開發(fā)板怎么操作
嵌入式系統(tǒng)中的實時操作系統(tǒng)
RT-Thread出席第六屆中國嵌入式技術(shù)大會,共話嵌入式操作系統(tǒng)與智能工業(yè)
![RT-Thread出席第六屆中國<b class='flag-5'>嵌入式</b>技術(shù)大會,共話<b class='flag-5'>嵌入式</b><b class='flag-5'>操作系統(tǒng)</b>與智能工業(yè)](https://file1.elecfans.com/web2/M00/C4/8A/wKgZomX0EhWACv8DAAAUet8ikhs451.png)
嵌入式系統(tǒng)怎么學(xué)?
如何提升嵌入式編程能力?
入門嵌入式系統(tǒng)這些知識你知道嗎?
再談嵌入式實時操作系統(tǒng)
![再談<b class='flag-5'>嵌入式</b>實時<b class='flag-5'>操作系統(tǒng)</b>](https://file1.elecfans.com/web2/M00/C8/81/wKgaomYVCTGAXoLNAAHKsmHXcPM241.png)
評論