C51 存儲類型、存儲模式、指針用法

在C51中對變量進行定義的格式如下:
【存儲種類】數(shù)據(jù)類型 【存儲器類型】 變量名列表;
其中存儲種類和存儲器類型是可選項,當變量名列表中的變量不止一個時,用逗號隔開。
存儲種類:4種
自動(auto),外部(extern),靜態(tài)(static)和寄存器(register)
存儲器類型:6種?
DATA區(qū)、BDATA區(qū)、IDATA區(qū)、PDATA區(qū)、XDATA區(qū)、CODE區(qū)? 指明該變量所處的內(nèi)存空間
存儲模式: 3種
SMALL、COMPACT和LARGE? 指明了變量在沒有指明存儲器類型時默認的存儲區(qū)域
1、存儲種類
自動(auto)變量
當變量的生命周期結束時,它所占的內(nèi)存單元也就被釋放。定義變量時省略存儲種類,則該變量默認為自動變量。
外部(extern)變量
假設一個變量在函數(shù)體外或別的程序中已被定義過,并且在本函數(shù)體內(nèi)要使用該變量,則該變量要在本函數(shù)體內(nèi)用extern 說明。用extern定義的變量稱為外部變量。外部變量被定義后,在程序的執(zhí)行過程中都是有效的。
靜態(tài)(static)變量
用static定義的變量稱為靜態(tài)變量。靜態(tài)變量在程序調(diào)用結束后其占用的內(nèi)存單元并不被釋放(其值保持不變)。
寄存器(register)變量
用register聲明的變量稱為寄存器變量。該類變量速度最快,應該存放使用頻率最高的變量。通常C51編譯器會自動識別程序中使用頻率最高的變量,并自動將其作為寄存器變量,程序員無需專門聲明。
變量的存儲種類和存儲器類型是不一樣的。存儲器類型指明該變量所處的內(nèi)存空間。單片機內(nèi)部有程序存儲器和數(shù)據(jù)存儲器。數(shù)據(jù)存儲器又分為片內(nèi)存儲器和片外存儲器。而片內(nèi)存儲器又分為低128字節(jié)和SFR特殊功能寄存器。

使用不同的存儲器類型,程序會有不同的執(zhí)行效率,在編寫C51程序時,推薦指定變量的存儲器類型,這樣有利于提高程序的執(zhí)行效率。
若省略存儲器類型,編譯器將根據(jù)使用的存儲器模式(SMALL,COMPACT,LARGE)來規(guī)定默認的存儲器類型。
2、六種存儲器類型
片內(nèi)RAM:DATA區(qū)、?BDATA區(qū)、?IDATA區(qū)
(1) DATA區(qū)
? ? ? 該區(qū)速度最快,所以應該存放使用頻率最高的變量。但是該區(qū)資源有限,除了存放變量外,還包含堆棧和寄存器組。一旦該區(qū)資源不夠,會使程序發(fā)生莫名其妙的錯誤。
固定指前面0x00-0x7f的128個字節(jié)RAM,可以用acc直接讀寫的,速度最快,生成的代碼也最小。
? 變量定義舉例: char data i[10];
(2) BDATA區(qū)
? ? ? 在該區(qū)定義的變量,可以進行位尋址,并且可以聲明位變量。它可以單獨使用變量的某一位,而不一定要用位變量名引用位變量。
注意該區(qū)不允許定義float類型的變量。
(3) IDATA區(qū)
該區(qū)使用寄存器間接尋址,可以存放使用比較頻繁的變量。變量定義舉例:?? float idata var;
固定指前面0x00-0xff的256個字節(jié)RAM,其中前128和data的128完全相同。
片外RAM:PDATA區(qū)、?XDATA區(qū)
(4) PDATA區(qū)
?該區(qū)只有一頁即256字節(jié),具體哪一頁由P2口指定。使用MOVX指令進行數(shù)據(jù)傳送。
?片外xdata的0X00–0XFF那一段,使用R0,R1間接尋址。
?變量定義舉例: long PDATA var
(5) XDATA區(qū)
該區(qū)和PDATA區(qū)類似,只是空間增大了——64KB。對XDATA的尋址比對PDATA的尋址要慢(前者需要裝入16位地址,而后者只需要裝載8位地址)。進行數(shù)據(jù)傳送時同樣需要使用MOVX指令。
? 變量定義舉例:unsigned char XDATA i;
(6) CODE區(qū)
該區(qū)為程序存儲器,代碼區(qū)中的數(shù)據(jù)一旦寫入不可擦除不可重寫。在該區(qū)中一般存放數(shù)據(jù)表,跳轉向量和狀態(tài)表等。變量定義舉例:
?變量定義舉例:unsigned char? CODE da[3]={0x04,0x58,0x56};
對于片外擴展I/O口,則要根據(jù)其硬件譯碼地址,將其視為片外數(shù)據(jù)存儲器的一個單元,在程序的開始位置使用#define 定義:
一旦在頭文件或程序中對這些片內(nèi)外I/O口進行定義以后,在程序中就可以自由使用這些I/O口了。
3、存儲模式
存儲模式指明了變量在沒有指明存儲器類型時默認的存儲區(qū)域,共有:SMALL、COMPACT和LARGE三種。
(1)SMALL模式
所有的缺省變量,參數(shù)都存儲在內(nèi)部RAM中,優(yōu)點:存儲速度快,執(zhí)行效率高。缺點:內(nèi)部RAM有限,只適合小程序。
(2)COMPACT模式
所有缺省變量都存儲在外部RAM的一頁(256字節(jié))中。具體哪一頁可由P2口指定,該模式空間較SMALL模式充裕,速度較SMALL模式慢,較LARGE模式快,是一種中間模式。
(3)LARGE模式
所有參數(shù)變量都放在片外數(shù)據(jù)存儲器中,容量大,但速度慢。
通過#pragma定義,例如#pragma small。
4、C51的指針
指針類型和存儲區(qū)的關系:
對變量進行聲明時可以指定變量的存儲類型如:
uchar data x和data uchar x相等價都是在內(nèi)ram區(qū)分配一個字節(jié)的變量。
1、普通指針:未指定指針指向
char * ptr; //指針占3字節(jié),第一字節(jié)是標識存儲類型,第二字節(jié)是指針高位字節(jié),第三字節(jié)是指針低位字節(jié)
指針指向的數(shù)據(jù)可以是片內(nèi)也可以是片外,由于片外數(shù)據(jù)地址在0x0000-0xffff之間,片內(nèi)數(shù)據(jù)地址在0x00-0xff之間,在未指定數(shù)據(jù)存儲在片內(nèi)還是片外的情況下,指針長度按固定3個字節(jié):一字節(jié)標識存儲類型+ 一字節(jié)高位地址+ 一字節(jié)低位地址。

存儲類型部分代表了該指針所指向的變量的存儲器類型,存儲類型的代碼如下:

2、內(nèi)存特殊指針:指定指針指向:
//在指定指針指向之后,指針就只需要表明地址即可,指針為1個字節(jié)或2個字節(jié)( one byte (idata, data, bdata, and pdata pointers) or two bytes (code and xdata pointers)),xdate是修飾 *的,也就是數(shù)據(jù)存儲在片外,此時ptr占兩個字節(jié)
總結:內(nèi)存特殊指針比一般指針運行快,因為數(shù)據(jù)存儲位置知道,編譯時可以優(yōu)化 指針類型可以轉換,但容易出錯。所以編程時最好對數(shù)據(jù)和對指針的修飾都要。

3、指針的絕對地址賦值
char xdata * XROM;
XROM=(char xdata *)0xB012;//指針XROM的值就是0xB012,(char xdata *)表示強制類型轉換
XROM=‘r’;//給0xB012的地址內(nèi)容賦值r
a=((char xdata *)0xB012);//等同于a=*XROM,此時a=‘r’
文章參考1:http://t.csdn.cn/JmNul
文章參考2:http://t.csdn.cn/E7GNQ 特別感謝以上博主的知識分享