<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > 嵌入式C語(yǔ)言中如何使用指針

嵌入式C語(yǔ)言中如何使用指針

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

本文引用地址:http://dyxdggzs.com/article/258222.htm

數據指針

  在嵌入式系統的編程中,常常要求在特定的內存單元讀寫(xiě)內容,匯編有對應的MOV指令,而除C/C++以外的其它編程語(yǔ)言基本沒(méi)有直接訪(fǎng)問(wèn)絕對地址的能力。在嵌入式系統的實(shí)際調試中,多借助C語(yǔ)言指針所具有的對絕對地址單元內容的讀寫(xiě)能力。以指針直接操作內存多發(fā)生在如下幾種情況:

  (1) 某I/O芯片被定位在CPU的存儲空間而非I/O空間,而且寄存器對應于某特定地址;

  (2) 兩個(gè)CPU之間以雙端口RAM通信,CPU需要在雙端口RAM的特定單元(稱(chēng)為mail box)書(shū)寫(xiě)內容以在對方CPU產(chǎn)生中斷;

  (3) 讀取在ROM或FLASH的特定單元所燒錄的漢字和英文字模。

  譬如:

unsigned char *p = (unsigned char *)0xF000FF00;
*p=11;

  以上程序的意義為在絕對地址0xF0000+0xFF00(80186使用16位段地址和16位偏移地址)寫(xiě)入11。

  在使用絕對地址指針時(shí),要注意指針自增自減操作的結果取決于指針指向的數據類(lèi)別。上例中p++后的結果是p= 0xF000FF01,若p指向int,即:

int *p = (int *)0xF000FF00;

  p++(或++p)的結果等同于:p = p+sizeof(int),而p-(或-p)的結果是p = p-sizeof(int)。

  同理,若執行:

long int *p = (long int *)0xF000FF00;

  則p++(或++p)的結果等同于:p = p+sizeof(long int) ,而p-(或-p)的結果是p = p-sizeof(long int)。

  記?。篊PU以字節為單位編址,而C語(yǔ)言指針以指向的數據類(lèi)型長(cháng)度作自增和自減。理解這一點(diǎn)對于以指針直接操作內存是相當重要的。



函數指針

  首先要理解以下三個(gè)問(wèn)題:

 ?。?)C語(yǔ)言中函數名直接對應于函數生成的指令代碼在內存中的地址,因此函數名可以直接賦給指向函數的指針;

 ?。?)調用函數實(shí)際上等同于調轉指令+參數傳遞處理+回歸位置入棧,本質(zhì)上最核心的操作是將函數生成的目標代碼的首地址賦給CPU的PC寄存器;

 ?。?)因為函數調用的本質(zhì)是跳轉到某一個(gè)地址單元的code去執行,所以可以調用一個(gè)根本就不存在的函數實(shí)體,暈?請往下看:

  請拿出你可以獲得的任何一本大學(xué)《微型計算機原理》教材,書(shū)中講到,186 CPU啟動(dòng)后跳轉至絕對地址0xFFFF0(對應C語(yǔ)言指針是0xF000FFF0,0xF000為段地 址,0xFFF0為段內偏移)執行,請看下面的代碼:



typedef void (*lpFunction) ( ); /* 定義一個(gè)無(wú)參數、無(wú)返回類(lèi)型的 */
/* 函數指針類(lèi)型 */
lpFunction lpReset = (lpFunction)0xF000FFF0; /* 定義一個(gè)函數指針,指向*/
/* CPU啟動(dòng)后所執行第一條指令的位置 */
lpReset(); /* 調用函數 */


  在以上的程序中,我們根本沒(méi)有看到任何一個(gè)函數實(shí)體,但是我們卻執行了這樣的函數調用:lpReset(),它實(shí)際上起到了軟重啟的作用,跳轉到CPU啟動(dòng)后第一條要執行的指令的位置。

  記?。汉瘮禑o(wú)它,唯指令集合耳;你可以調用一個(gè)沒(méi)有函數體的函數,本質(zhì)上只是換一個(gè)地址開(kāi)始執行指令!

  數組vs.動(dòng)態(tài)申請

  在嵌入式系統中動(dòng)態(tài)內存申請存在比一般系統編程時(shí)更嚴格的要求,這是因為嵌入式系統的內存空間往往是十分有限的,不經(jīng)意的內存泄露會(huì )很快導致系統的崩潰。

  所以一定要保證你的malloc和free成對出現,如果你寫(xiě)出這樣的一段程序:



char * function(void)
{
 char *p;
 p = (char *)malloc(…);
 if(p==NULL)
  …;
  … /* 一系列針對p的操作 */
 return p;
}


  在某處調用function(),用完function中動(dòng)態(tài)申請的內存后將其free,如下:



char *q = function();

free(q);



  上述代碼明顯是不合理的,因為違反了malloc和free成對出現的原則,即誰(shuí)申請,就由誰(shuí)釋放原則。不滿(mǎn)足這個(gè)原則,會(huì )導致代碼的耦合度增大,因為用戶(hù)在調用function函數時(shí)需要知道其內部細節!

  正確的做法是在調用處申請內存,并傳入function函數,如下:



char *p=malloc(…);
if(p==NULL)
…;
function(p);

free(p);
p=NULL;



  而函數function則接收參數p,如下:



void function(char *p)
{
 … /* 一系列針對p的操作 */
}


  基本上,動(dòng)態(tài)申請內存方式可以用較大的數組替換。對于編程新手,筆者推薦你盡量采用數組!嵌入式系統可以以博大的胸襟接收瑕疵,而無(wú)法海納錯誤。畢竟,以最笨的方式苦練神功的郭靖勝過(guò)機智聰明卻范政治錯誤走反革命道路的楊康。

  給出原則:

 ?。?)盡可能的選用數組,數組不能越界訪(fǎng)問(wèn)(真理越過(guò)一步就是謬誤,數組越過(guò)界限就光榮地成全了一個(gè)混亂的嵌入式系統);

 ?。?)如果使用動(dòng)態(tài)申請,則申請后一定要判斷是否申請成功了,并且malloc和free應成對出現!



評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>