注意 keil 中帶有reentrant關鍵字的函式是不同於這裡將要說的東西(如 void myfunc(void)reentrant)
//在keil 中的compact (變數被定義在pdata中) 模式不能被定義
void main (void)
在keil 中 有data 、idata 、pdata 、xdata 這幾種對變數在記憶體中規定(後面將說到code、bdata、sfr、16sfr、bit、sbit)
//在c51的幫助中都有
unsigned char data variable; //變數的位址在ram上(最大為128 bytes)
unsigned char idata variable; //變數的位址在ram上(最大為256 bytes)
unsigned char pdata variable; //變數的位址在外部擴充套件ram上(256 bytes 每頁)
unsigned char xdata variable; //變數的位址在外部擴充套件ram上(最大為64k bytes)
在編譯時分配位址給變數,在生成二進位制**時把變數寫成對應的位址,在程式寫好後,記憶體就已經分配好,
13: void main (void)
14:
c:0x000f 22 ret
在沒有作業系統的支援時,變數的定義都是一次性的,沒有誰來**過期的記憶體單元。乙個函式中定義了,就再也不能在另乙個函式中使用這個
位址,除非是全域性的。這也引出了一種使用記憶體的方法(全部定義成全域性的,不使用區域性變數,不使用引數);
c:0x0000 02002b ljmp c:002b
6: void main (void)
7:
函式的引數與記憶體分配!【compact模式下】
//如果下面的**中的 int pdata pd[124]; 中124改為比他跟大的數,將通不過編譯
//通過檢視彙編**可知:函式的引數也是要佔記憶體空間的,這裡通過r0~r7暫存器組來傳遞!
13: void main (void)
14:
c:0x002a 22 ret
3: void func1 (int s ,int k) ;編譯函式時引數的位址就固定了!
c:0x002b 7800 mov r0,#0x00 ;通過r0傳遞引數
c:0x002d ee mov a,r6
c:0x002e f2 movx @r0,a
c:0x002f 08 inc r0
c:0x0030 ef mov a,r7
c:0x0031 f2 movx @r0,a
c:0x0032 08 inc r0
c:0x0033 ec mov a,r4
c:0x0034 f2 movx @r0,a
c:0x0035 08 inc r0
c:0x0036 ed mov a,r5
c:0x0037 f2 movx @r0,a
4:
7:
c:0x0038 22 ret
8: void func2 (int s ,int k) ;編譯函式時引數的位址就固定了!
c:0x0039 7804 mov r0,#0x04 ;通過r0傳遞引數
c:0x003b ee mov a,r6
c:0x003c f2 movx @r0,a
c:0x003d 08 inc r0
c:0x003e ef mov a,r7
c:0x003f f2 movx @r0,a
c:0x0040 08 inc r0
c:0x0041 ec mov a,r4
c:0x0042 f2 movx @r0,a
c:0x0043 08 inc r0
c:0x0044 ed mov a,r5
c:0x0045 f2 movx @r0,a
9:
//從上面(還有實驗結果)可以看出對字串和其他變數的記憶體分配是不一樣的!
//在vs2005中
void main (void)
void main (void );}
//初步分析,字串被分配到了**段中!是不能被訪問的!
+ bmp 0x0012ff48 "12345678990" char [10]
+ p 0x00415650 "aaa" char *
//他們被分配的位址相差很多
///其他型別(keil中)[可以參看c51的幫助]
code ///function的預設型別 char code ar[100]; 也可以把變數放到code段
bit //申明乙個位變數
static bit done_flag = 0; /* bit variable */
sfr、sfr16 特殊功能暫存器
sfr psw = 0xd0;
sfr16 t2 = 0xcc; /* timer 2: t2l 0cch, t2h 0cdh */
sbit 特殊功能暫存器的位
sbit name = sfr-address ^ bit-position;
bdata //申明可位定址的變數
//另外,指標所佔的位元組數也和data/xdata。。。有關
char data *p; //p 佔1 個位元組
char xdata *p; //p 佔3 個位元組
結束!做一點補充:
void func(void)
void func2(void)
void main(void)
func,和func2兩個函式所占用的總記憶體不是200,而是100,c51處理區域性變數不是通過堆疊來實現的,而是從固定位址開始分配變數0x08,0x09..... 這是我以前一直誤會的地方,以前總以為c51沒有用堆疊操作零時變數,所以每個函式中的變數都占用不同的位址,所以為了節省記憶體空間到處分配全域性變數!!
指標 指標變數與記憶體空間 解惑
指標 指標變數與記憶體空間 解惑 一年前,我曾今在chinaunix寫過一篇部落格 關於定義乙個指標與指標變數 然後搬家來了csdn。這篇部落格中寫道了很多關於指標和指標變數以及空間分配的一些常見錯誤。但是,到現在為止,無論是csdn的還是一些已經工作的同事以及大三大四的學生,陸陸續續的有人在問我關...
程序位址空間與虛擬儲存空間的理解
在進入正題前先來談談作業系統記憶體管理機制的發展歷程,了解這些有利於我們更好的理解目前作業系統的記憶體管理機制。一 早期的記憶體分配機制 在 早期的計算機中,要執行乙個程式,會把這些程式全都裝入記憶體,程式都是直接執行在記憶體上的,也就是說程式中訪問的記憶體位址都是實際的物理記憶體位址。當計算機同時...
程序位址空間與虛擬儲存空間的理解
筆記 程式編譯後檔案包含程序空間資訊,執行的時候並不是完全載入記憶體,是按分頁訪問到哪個頁面才載入虛擬記憶體位址對映到得物理記憶體位址空間。在進入正題前先來談談作業系統記憶體管理機制的發展歷程,了解這些有利於我們更好的理解目前作業系統的記憶體管理機制。一 早期的記憶體分配機制 在早期的計算機中,要執...