天天看點

C51 存儲類型與存儲模式

在C51中對變量進行定義的格式如下:

【存儲種類】資料類型 【存儲器類型】 變量名清單;

 其中存儲種類和存儲器類型是可選項,當變量名清單中的變量不止一個時,用逗号隔開。

存儲種類:4種

自動(auto),外部(extern),靜态(static)和寄存器(register)

存儲器類型:6種 

DATA區、BDATA區、IDATA區、PDATA區、XDATA區、CODE區  指明該變量所處的記憶體空間

存儲模式: 3種

SMALL、COMPACT和LARGE  指明了變量在沒有指明存儲器類型時預設的存儲區域

1、存儲種類

自動(auto)變量

當變量的生命周期結束時,它所占的記憶體單元也就被釋放。定義變量時省略存儲種類,則該變量預設為自動變量。

int i=10;

          ……

          }

         main()

         {……

         add();在調用add()子函數時為i配置設定記憶體單元,調用結束後變量i所占用的記憶體被釋放。

         ……  

         }      
C51 存儲類型與存儲模式

外部(extern)變量

假設一個變量在函數體外或别的程式中已被定義過,并且在本函數體内要使用該變量,則該變量要在本函數體内用extern 說明。用extern定義的變量稱為外部變量。外部變量被定義後,在程式的執行過程中都是有效的。

靜态(static)變量

用static定義的變量稱為靜态變量。靜态變量在程式調用結束後其占用的記憶體單元并不被釋放(其值保持不變)。

寄存器(register)變量

用register聲明的變量稱為寄存器變量。該類變量速度最快,應該存放使用頻率最高的變量。通常C51編譯器會自動識别程式中使用頻率最高的變量,并自動将其作為寄存器變量,程式員無需專門聲明。

變量的存儲種類和存儲器類型是不一樣的。存儲器類型指明該變量所處的記憶體空間。單片機内部有程式存儲器和資料存儲器。資料存儲器又分為片記憶體儲器和片外存儲器。而片記憶體儲器又分為低128位元組和SFR特殊功能寄存器。

C51 存儲類型與存儲模式

      使用不同的存儲器類型,程式會有不同的執行效率,在編寫C51程式時,推薦指定變量的存儲器類型,這樣有利于提高程式的執行效率。

若省略存儲器類型,編譯器将根據使用的存儲器模式(SMALL,COMPACT,LARGE)來規定預設的存儲器類型。

六種存儲器類型

(1) DATA區

      該區速度最快,是以應該存放使用頻率最高的變量。但是該區資源有限,除了存放變量外,還包含堆棧和寄存器組。一旦該區資源不夠,會使程式發生莫名其妙的錯誤。

  變量定義舉例: char data i[10];

(2) BDATA區

      在該區定義的變量,可以進行位尋址,并且可以聲明位變量。它可以單獨使用變量的某一位,而不一定要用位變量名引用位變量。

   例如:

unsigned char bdata status;

     if(status^5)

     {

       …………

      }      
C51 存儲類型與存儲模式

   注意該區不允許定義float類型的變量。

(3) IDATA區

該區使用寄存器間接尋址,可以存放使用比較頻繁的變量。變量定義舉例:   float idata var;

(4) PDATA區

 該區隻有一頁即256位元組,具體哪一頁有P2口指定。使用MOVX指令進行資料傳送。

 變量定義舉例: long PDATA var

(5) XDATA區

該區和PDATA區類似,隻是空間增大了——64KB。對XDATA的尋址比對PDATA的尋址要慢(前者需要裝入16位位址,而後者隻需要裝載8位位址)。進行資料傳送時同樣需要使用MOVX指令。

  變量定義舉例:unsigned char XDATA i;

(6) CODE區

該區為程式存儲器,代碼區中的資料一旦寫入不可擦除不可重寫。在該區中一般存放資料表,跳轉向量和狀态表等。變量定義舉例:

 變量定義舉例:unsigned char  CODE da[3]={0x04,0x58,0x56};

對于片外擴充I/O口,則要根據其硬體譯碼位址,将其視為片外資料存儲器的一個單元,在程式的開始位置使用#define 定義:

   例:

#define <absacc.h>

#define

/*将PORTA定義為外部I/O口,其位址為0x8003*/,長度為一個位元組。      
C51 存儲類型與存儲模式
  • 一旦在頭檔案或程式中對這些片内外I/O口進行定義以後,在程式中就可以自由使用這些I/O口了。

2、存儲模式

存儲模式指明了變量在沒有指明存儲器類型時預設的存儲區域,共有:SMALL、COMPACT和LARGE三種。

(1)SMALL模式

所有的預設變量,參數都存儲在内部RAM中,優點:存儲速度快,執行效率高。缺點:内部RAM有限,隻适合小程式。

(2)COMPACT模式

所有預設變量都存儲在外部RAM的一頁(256位元組)中。具體哪一頁可有P2口指定,該模式空間較SMALL模式充裕,速度較SMALL模式慢,較LARGE模式快,是一種中間模式。

(3)LARGE模式

所有參數變量都放在片外資料存儲器中,容量大,但速度慢。

  • 通過#pragma定義,例如#pragma small。

3、指針的存儲類型

  C51編譯器支援兩種不同類型的指針:存儲器指針和通用指針

(1)通用指針

    通用或未定型的指針的聲明和标準C語言中一樣。

  如 :  char *s;      /* string ptr */

         int *numptr;  /* int ptr */

         long *state;  /* long ptr */

通用指針總是需要三個位元組來存儲,第一個位元組是用來表示存儲

器類型,第二個位元組是指針的高位元組,第三位元組是指針的低位元組

C51 存儲類型與存儲模式

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

C51 存儲類型與存儲模式

通用指針可以用來通路所有類型的變量,而不管變量存儲在哪個存儲空間中,因而許多庫函數都使用通用指針。通用指針很友善,但是也很慢,在所指向目标的存儲空間不明确的情況下它們用的最多。

(2)存儲器指針

    存儲器指針或類型确定的指針,在定義時包括一個存儲器類型說明,并且總是指向此說明的特定存儲器空間,例如:

  char data *str;    /* ptr to string in data */

  int xdata *numtab; /* ptr to int(s) in xdata */

  long code *powtab; /* ptr to long(s) in code */

正是由于存儲器類型在編譯時已經确定,通用指針中用來表示存儲器類型的位元組就不再需要了。指向idata、data、bdata和pdata的存儲器指針用一個位元組儲存,指向code和xdata的存儲器指針用兩個位元組儲存,使用存儲器指針比通用指針效率要高,速度要快。