c
語言嵌入式系統程式設計修煉之記憶體操作
資料指標
在嵌入式系統的程式設計中,常常要求在特定的記憶體單元讀寫內容,彙編有對應的
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啟動後第一條要執
行的指令的位置。
記住:函式無它,唯指令集合耳;你可以呼叫乙個沒有函式體的函式,本質上只是
換乙個位址開始執行指令!
Crack C語言之 指標之六
再一次吃驚 陣列的陣列與多維陣列的區別 看見這個題目,也許有些人就會嘀咕了 難道兩者不是一樣的嗎?c語言的多維陣列不就是陣列的陣列嗎?不!兩者是有區別的,而且還不小呢。首先看看兩者的共同點 1。記憶體映象一樣。2。陣列引用方式一樣,都是 陣列名 下標 下標 3。陣列名都是陣列的首位址,都是乙個符號位...
C語言之指標二
函式指標 如果在程式定義了乙個函式,在編譯時,編譯系統為函式 分配一段儲存空間,這段儲存空間的起始位址,稱為這個函式的指標 函式名就是函式開始的位址 函式二級指標可以修改函式指標的指向 函式指標,不僅僅是位址,必須明確函式指標型別和輸出引數型別和數量 函式名可以作為引數傳遞給函式指標 include...
C語言之指標(二)
二 指標變數做函式引數 在使用函式時我們一般都使用的是基本型別做函式引數,如 int double float等等。那在使用指標變數做函式引數和基本型別做函式引數有什麼不同呢?1 在使用基本型別做函式引數時是把實參的值傳遞給形參,在被調函式中形參值的改變不能改變主函式中實參的值,如下 這個程式是想通...