精品国产成人一区二区三区-女子十八毛片-欧洲性猛交-无码不卡一区二区三区在线观看-www.四虎在线-伊人网国产-国精产品自偷自偷综合下载-不卡av网站-俄罗斯黄色大片-一本久久知道综合久久-国产精品日韩一区二区-日韩精品色-免费人成网ww555kkk在线-黄色在线观看免费-日韩在线免费-久久久久99人妻一区二区三区-十八禁真人啪啪免费网站

機(jī)電之家資源網(wǎng)
單片機(jī)首頁|單片機(jī)基礎(chǔ)|單片機(jī)應(yīng)用|單片機(jī)開發(fā)|單片機(jī)文案|軟件資料下載|音響制作|電路圖下載 |嵌入式開發(fā)
培訓(xùn)信息
贊助商
C語言嵌入式系統(tǒng)編程修煉之內(nèi)存操作
C語言嵌入式系統(tǒng)編程修煉之內(nèi)存操作
 更新時(shí)間:2009-11-20 16:38:25  點(diǎn)擊數(shù):0
【字體: 字體顏色

在嵌入式系統(tǒng)的編程中,常常要求在特定的內(nèi)存單元讀寫內(nèi)容,匯編有對(duì)應(yīng)的MOV指令,而除C/C++以外的其它編程語言基本沒有直接訪問絕對(duì)地址的能力.在嵌入式系統(tǒng)的實(shí)際調(diào)試中,多借助C語言指針?biāo)哂械膶?duì)絕對(duì)地址單元內(nèi)容的讀寫能力.以指針直接操作內(nèi)存多發(fā)生在如下幾種情況:

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

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

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

  譬如:

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

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

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

int *p = (int *)0xF000FF00;

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

  同理,若執(zhí)行:

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

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

  記住:CPU以字節(jié)為單位編址,而C語言指針以指向的數(shù)據(jù)類型長度作自增和自減.理解這一點(diǎn)對(duì)于以指針直接操作內(nèi)存是相當(dāng)重要的.

  函數(shù)指針

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

  (1)C語言中函數(shù)名直接對(duì)應(yīng)于函數(shù)生成的指令代碼在內(nèi)存中的地址,因此函數(shù)名可以直接賦給指向函數(shù)的指針;

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

  (3)因?yàn)楹瘮?shù)調(diào)用的本質(zhì)是跳轉(zhuǎn)到某一個(gè)地址單元的code去執(zhí)行,所以可以"調(diào)用"一個(gè)根本就不存在的函數(shù)實(shí)體,暈?請(qǐng)往下看:

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

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

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

  記住:函數(shù)無它,唯指令集合耳;你可以調(diào)用一個(gè)沒有函數(shù)體的函數(shù),本質(zhì)上只是換一個(gè)地址開始執(zhí)行指令!

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

  在嵌入式系統(tǒng)中動(dòng)態(tài)內(nèi)存申請(qǐng)存在比一般系統(tǒng)編程時(shí)更嚴(yán)格的要求,這是因?yàn)榍度胧较到y(tǒng)的內(nèi)存空間往往是十分有限的,不經(jīng)意的內(nèi)存泄露會(huì)很快導(dǎo)致系統(tǒng)的崩潰.

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

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

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

char *q = function();

free(q);

  上述代碼明顯是不合理的,因?yàn)檫`反了malloc和free成對(duì)出現(xiàn)的原則,即"誰申請(qǐng),就由誰釋放"原則.不滿足這個(gè)原則,會(huì)導(dǎo)致代碼的耦合度增大,因?yàn)橛脩粼谡{(diào)用function函數(shù)時(shí)需要知道其內(nèi)部細(xì)節(jié)!

  正確的做法是在調(diào)用處申請(qǐng)內(nèi)存,并傳入function函數(shù),如下:

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

free(p);
p=NULL;

  而函數(shù)function則接收參數(shù)p,如下:

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


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

  給出原則:

  (1)盡可能的選用數(shù)組,數(shù)組不能越界訪問(真理越過一步就是謬誤,數(shù)組越過界限就光榮地成全了一個(gè)混亂的嵌入式系統(tǒng));

  (2)如果使用動(dòng)態(tài)申請(qǐng),則申請(qǐng)后一定要判斷是否申請(qǐng)成功了,并且malloc和free應(yīng)成對(duì)出現(xiàn)!

關(guān)鍵字const

  const意味著"只讀".區(qū)別如下代碼的功能非常重要,也是老生長嘆,如果你還不知道它們的區(qū)別,而且已經(jīng)在程序界摸爬滾打多年,那只能說這是一個(gè)悲哀:

const int a;
int const a;
const int *a;
int * const a;
int const * a const;

  • 上一篇: PIC16F74電動(dòng)按摩椅的研制
  • 下一篇: 沒有了
  • 發(fā)表評(píng)論   告訴好友   打印此文  收藏此頁  關(guān)閉窗口  返回頂部
    熱點(diǎn)文章
     
    推薦文章
     
    相關(guān)文章
    網(wǎng)友評(píng)論:(只顯示最新5條。)
    關(guān)于我們 | 聯(lián)系我們 | 廣告合作 | 付款方式 | 使用幫助 | 機(jī)電之家 | 會(huì)員助手 | 免費(fèi)鏈接

    點(diǎn)擊這里給我發(fā)消息66821730(技術(shù)支持)點(diǎn)擊這里給我發(fā)消息66821730(廣告投放) 點(diǎn)擊這里給我發(fā)消息41031197(編輯) 點(diǎn)擊這里給我發(fā)消息58733127(審核)
    本站提供的機(jī)電設(shè)備,機(jī)電供求等信息由機(jī)電企業(yè)自行提供,該企業(yè)負(fù)責(zé)信息內(nèi)容的真實(shí)性、準(zhǔn)確性和合法性。
    機(jī)電之家對(duì)此不承擔(dān)任何保證責(zé)任,有侵犯您利益的地方請(qǐng)聯(lián)系機(jī)電之家,機(jī)電之家將及時(shí)作出處理。
    Copyright 2007 機(jī)電之家 Inc All Rights Reserved.機(jī)電之家-由機(jī)電一體化網(wǎng)更名-聲明
    電話:0571-87774297 傳真:0571-87774298
    杭州濱興科技有限公司提供技術(shù)支持

    主辦:杭州市高新區(qū)(濱江)機(jī)電一體化學(xué)會(huì)
    中國行業(yè)電子商務(wù)100強(qiáng)網(wǎng)站

    網(wǎng)站經(jīng)營許可證:浙B2-20080178-1
    遵义市| 阿克陶县| 常熟市| 武夷山市| 垣曲县| 高阳县| 阿拉善左旗| 湟中县| 台中市| 白城市| 深圳市| 稷山县| 通榆县| 莱州市| 广平县| 山西省| 新野县| 石渠县| 台北县| 泽普县| 舒兰市| 同仁县| 永清县| 江北区| 莱阳市| 招远市| 大厂| 贵德县| 河西区| 合肥市| 苍南县| 虞城县| 镇平县| 台前县| 双桥区| 沁源县| 南昌市| 会理县| 中卫市| 秀山| 青浦区|