男女午夜激情_www.天堂av.com_亚洲综合小说区_亚洲欧美自拍视频_成年精品_久久www免费人成—看片_激情综合五月天_久久高潮视频_最新国产成人ab网站_国产精品卡一

機電之家資源網
單片機首頁|單片機基礎|單片機應用|單片機開發|單片機文案|軟件資料下載|音響制作|電路圖下載 |嵌入式開發
培訓信息
贊助商
C語言嵌入式系統編程修煉之內存操作
C語言嵌入式系統編程修煉之內存操作
 更新時間:2009-11-20 16:38:25  點擊數:0
【字體: 字體顏色

在嵌入式系統的編程中,常常要求在特定的內存單元讀寫內容,匯編有對應的MOV指令,而除C/C++以外的其它編程語言基本沒有直接訪問絕對地址的能力.在嵌入式系統的實際調試中,多借助C語言指針所具有的對絕對地址單元內容的讀寫能力.以指針直接操作內存多發生在如下幾種情況:

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

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

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

  譬如:

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

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

  在使用絕對地址指針時,要注意指針自增自減操作的結果取決于指針指向的數據類別.上例中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).

  記住:CPU以字節為單位編址,而C語言指針以指向的數據類型長度作自增和自減.理解這一點對于以指針直接操作內存是相當重要的.

  函數指針

  首先要理解以下三個問題:

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

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

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

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

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

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

  記住:函數無它,唯指令集合耳;你可以調用一個沒有函數體的函數,本質上只是換一個地址開始執行指令!

  數組vs.動態申請

  在嵌入式系統中動態內存申請存在比一般系統編程時更嚴格的要求,這是因為嵌入式系統的內存空間往往是十分有限的,不經意的內存泄露會很快導致系統的崩潰.

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

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

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

char *q = function();

free(q);

  上述代碼明顯是不合理的,因為違反了malloc和free成對出現的原則,即"誰申請,就由誰釋放"原則.不滿足這個原則,會導致代碼的耦合度增大,因為用戶在調用function函數時需要知道其內部細節!

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

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

free(p);
p=NULL;

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

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


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

  給出原則:

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

  (2)如果使用動態申請,則申請后一定要判斷是否申請成功了,并且malloc和free應成對出現!

關鍵字const

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

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

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

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

    主辦:杭州市高新區(濱江)機電一體化學會
    中國行業電子商務100強網站

    網站經營許可證:浙B2-20080178-1
    主站蜘蛛池模板: 科技| 高青县| 靖远县| 亳州市| 贵德县| 水富县| 迭部县| 缙云县| 永城市| 敦化市| 嘉峪关市| 名山县| 渭南市| 山西省| 安国市| 武隆县| 上杭县| 鹤山市| 西充县| 清远市| 晴隆县| 吕梁市| 房山区| 瑞昌市| 华阴市| 昆山市| 都兰县| 荥经县| 普洱| 长子县| 孟津县| 台北县| 临沭县| 鹤峰县| 江油市| 彭山县| 昌平区| 辉南县| 许昌县| 崇文区| 乐业县|