日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > 單片機 > 單片機
[導讀]一、全局變量和局部變量全局變量和局部變量的區(qū)別在于作用域的不同。此外還有靜態(tài)全局變量和靜態(tài)局部變量。全局變量作用域為全局,在一個源文件中定義,其他的源文件也可以應用。在其他的源文件中使用extern加以聲明

一、全局變量和局部變量

全局變量和局部變量的區(qū)別在于作用域的不同。此外還有靜態(tài)全局變量和靜態(tài)局部變量。

全局變量作用域為全局,在一個源文件中定義,其他的源文件也可以應用。在其他的源文件中使用extern加以聲明;

靜態(tài)全局變量作用域為該源文件,只作用在聲明它的源文件中,通過static聲明,這樣即使在其他的源文件中有相同名稱的變量也不相同;

局部變量作用域為函數內部。當函數被調用時,為其分配空間,函數調用完成后收回內存,銷毀變量;

局部靜態(tài)變量作用域為局部,只被初始化一次,但是在后面它一直存在。即使函數調用完成后也一直存在。

全局變量和局部變量都是要分配內存的,它們的區(qū)別只是在于作用域不同。

在C中,全局變量、靜態(tài)全局變量及靜態(tài)局部變量都在靜態(tài)存儲區(qū),由于這些變量的生存周期較長,占有較多的內存但是由于已經分配好了內存,因此速度較快,而局部變量則在棧中分配空間。在KeilC51中這是不同的。

二、C51中的全局變量和局部變量

在51中程序ROM和數據RAM是嚴格分開的,特殊功能寄存器與片內數據存儲器統(tǒng)一編址。這與其他一般的微機不同。51中內部的RAM有256字節(jié),外部可尋址64KB,對于256字節(jié),其中前128字節(jié)(00-7FH)又分為三部分:通用寄存器組、可位尋址區(qū)、用戶RAM區(qū);高128字節(jié)(7F-FF)為SFR。上電復位后堆棧指針指向07H,在通用寄存器區(qū),此時對戰(zhàn)區(qū)占用1,2,3組寄存器,但是用戶可自行將sp設置在30-7F。

C51編譯器通過將變量定義為不同的類型,來區(qū)分不同的存儲區(qū),常用的變量類型有:

data:片內RAM的低128字節(jié)

bdata:可位尋址的片內RAM

以上兩種類型可以快速的存取數據,常用來放臨時性的傳遞變量或使用頻率較高的變量。

idata:整個片內RAM。

xdata:片外存儲區(qū)(64KB),由于在對片外存儲區(qū)操作時,需要先將數據移到片內,進行處理后再存儲到片外,因此常用來存放不常用的變量,或收集待處理的數據,或存放要被發(fā)往另一臺計算機的數據。

pdata:屬于xdata類型,由于它的高字節(jié)保存在P2口中,只能尋址256字節(jié)。

code:ROM內,數據不會丟失。

此外,C51還有三種存儲模式:SMALL, COMPACT, LARGE

SMALL模式下,如果不做特別說明,參數及局部變量默認為data型,放在片內RAM128字節(jié)內,訪問迅速。由于內部的RAM有限,如果變量過多,會導致頻繁的使用寄存器,而使代碼變的冗長。此時棧也在片內的RAM,棧長很關鍵,因為棧長依賴于不同函數的嵌套層數。

COMPACT:不做特別說明,參數及局部變量默認為pdata,??臻g在內部RAM。

LARGE:參數及局部變量默認為xdata,使用DPTR來尋址。訪問效率低,此外這種數據指針不能對稱操作。

全局變量會根據定義的類型或者存儲的模式分配在相應的存儲區(qū)內,有固定的地址,如果全局變量過多則會導致占用太多內存,處理速度變慢。

三、共享和覆蓋

由于51的存儲區(qū)有限,因此變有了覆蓋和共享的概念。

共享:有共享變量和共享函數,共享是針對全局變量或靜態(tài)變量而言的,對全局變量定義后就對其分配了內存,在任何函數或者程序中都可以共享該變量的內存,在其他的文件中也可以通過聲明extern來實現共享。共享函數也是類同。

覆蓋:如果一個程序不再被調用,也不由其他的程序調用,在其他的程序運行之前程序也不在運行,那么這個程序的變量可以放在與其他的程序完全相同的RAM空間,這就是覆蓋。

對于函數之間的覆蓋在Keil中有一段描述:

The system the linker uses to determine which function arguments (or parameters) and variables may be overlaid is quite sophisticated. It begins when the compiler generates the object code for a function.

The compiler stores all function parameters and local variables in overlayable bit, data, pdata, or xdata segments. The segment names generated by the compiler forParameters and Local Variablesare well-defined. They are used by the compiler to access parameters and local variables.

As the linker resolves references between functions, it builds a call tree based on where those references appear. For instance, iffunction_acallsfunction_b, the compiler inserts a reference tofunction_bin the object code generated forfunction_a. When the linker resolves this reference, it inserts the address offunction_band adds a call fromfunction_atofunction_bin the call tree.

The local variables and parameters offunction_aare overlaid with the variables and parameters offunction_bonly under the following conditions:

No call references of any kind may exist betweenfunction_aandfunction_b. This includes direct calls between A and B as well as calls from other functions on the A branch to B and calls from functions on the B branch to A.

The functions A and B may be invoked by only one program event or root: either the main root or an interrupt but not both. It is impossible to overlay variables and parameters if a function is called by an interrupt and the main program or by two interrupts.

The segment definitions of functions A and B must conform to the rules for segment names described in the compiler manual.

在函數中定義的動態(tài)局部變量可以被覆蓋,一個函數說明的變量在下一次進入函數時不同,即函數調用時會發(fā)生變化(函數調用時才為局部變量分配空間,因此每次調用分配的地址可能不同)。有一些編譯器通常把局部變量放在堆棧上,這樣運行起來位置不固定,棧操作不方便,而在51的編譯器中則監(jiān)視函數調用的嵌套順序,把幾個函數的變量放在同樣固定的位置。在51編譯器中連接器會搜索所有函數中局部變量占用存儲區(qū)間最多的函數,然后已這個函數的局部變量的占用的空間的多少開辟一片空間,其他函數的局部變量也放在該空間中,同時實現了變量的覆蓋(無相互調用)與地址的共享。例如函數A占10個字節(jié),函數B占20個字節(jié),函數C占15個字節(jié),如果它們之間沒有相互調用則僅需20個字節(jié)就可以滿足45個字節(jié)的變量需要。

C51中根據變量定義是的數據類型在相應的存儲區(qū)內為變量分配內存,在內部整個RAM區(qū)中,先為定義在該端的全局變量分配地址,然后是程序中所有函數的參數和局部變量的覆蓋區(qū)(內部RAM存取迅速)。以上兩部分內存都是上面所說的C中的靜態(tài)存儲區(qū)(段)。接下來就是系統(tǒng)的堆棧,棧底有?STACK自動生成,棧頂在0xFF。

正是由于所有函數的參數和局部變量的共享一個覆蓋區(qū),函數沒有相互的調用時,在執(zhí)行一個函數時,會將另一個函數的變量的存儲區(qū)覆蓋。如果函數有調用,那么不會覆蓋原來函數的局部變量的區(qū)間,但如果函數的嵌套(遞歸)層數太多,所有的變量的內存大于了覆蓋區(qū)時,一個函數的內部的變量可能會被新調用的函數沖掉,再返回該函數時,無法找到相應變量的內存,也就無法找到該變量的值。通過聲明為可重入函數,讓參數和變量放在堆棧中。

對于覆蓋,大多人認為是為了節(jié)省內存,但網上有另一種說法,個人覺得很有道理,引用如下:

一般的C編譯器(或者更確切點地說:基于一般的處理器上的C編譯器),其函數的局部變量是存放于堆棧中的,而C51是存放于一個可覆蓋的(數據)段中的.

  至于C51這樣做的原因,不是象有些人說的那樣,為了節(jié)約內存.事實上,這樣做根本節(jié)約不了內存.理由如下:

  1) 如果一個函數func1調用另一個函數func2,那么func1,func2的局部變量根本就不能是同一塊內存.C51還是要為他們分配不同的RAM.這跟使用堆棧相比,節(jié)約不了內存.

  2) 如果func1,func2不是在一個調用鏈上,那么C51可以通過覆蓋分析,讓它們的局部變量共享相同的內存地址.但這樣也不會比使用堆棧節(jié)約內存.因為既然它們是在不同的調用鏈上,那么當其中一個函數運行時,那么另外一個函數必然不在其生命期內,它所占用的堆棧也已釋放,歸還給系統(tǒng).

  真實的原因(C51使用覆蓋段作為局部變量的存放地的原因)是:

  51的指令系統(tǒng)沒有一個有效的相對尋址(變址尋址)的指令,這使得使用堆棧作為變量的代價太過昂貴.

  使用堆棧存放變量的一般做法是:

  進入函數時,保留一段堆??臻g,作為變量的存放空間,用一個可作為基址尋址的寄存器指向這個空間,通過加上一個偏移量,就可以訪問不同的變量了.

  例如: MOV EAX, [EBP + 14];X86指令

  LDR R0, [R12, #14];ARM指令

  都可以很好的解決這個問題.

  但51缺少這樣的指令.

  *其實,51中還是有2個可變址尋址的指令的,但不適合訪問堆棧的局部變量這樣的場合.

  MOVC A, @A+DPTR

  MOVC A, @A+PC

  所以,C51有個特別的關鍵字: reentrant 用來解決函數重入的問題。


本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

上?!?025年6月20日 在2025亞馬遜云科技中國峰會上,全球知名的汽車制造商長城汽車宣布應用亞馬遜云科技Amazon Connect構建全球聯(lián)絡中心,實現了全球客服從統(tǒng)一渠道、客戶投訴分級與跟進、閉關管理到統(tǒng)計考...

關鍵字: 計算 存儲 數據庫

上?!?025年6月19日,亞馬遜云科技中國峰會在上海召開。峰會期間,亞馬遜全球副總裁、亞馬遜云科技大中華區(qū)總裁儲瑞松全面闡述了隨著生成式AI場景和應用的快速落地,AI發(fā)展也迎來Agentic AI技術的爆發(fā),企業(yè)需要...

關鍵字: AI 存儲 大數據

5月14日消息,西部數據將NAND閃存和SSD固態(tài)硬盤業(yè)務交給子品牌閃迪剛剛兩個月,沒想到這么快就完成了過渡!

關鍵字: 閃迪 存儲

Microchip致力于提供創(chuàng)新、安全且可擴展的生態(tài)系統(tǒng),以支持現代服務器業(yè)務的發(fā)展

關鍵字: AI數據中心 存儲 計算

5月8日消息,NEO Semiconductor近日宣布推出兩項新的3D X-DRAM單元設計——1T1C和3T0C,有望徹底改變DRAM內存的現狀。

關鍵字: X-DRAM 內存 存儲

在數字化浪潮中,個人數據存儲與管理的需求日益凸顯,但傳統(tǒng)NAS設備復雜的使用門檻總讓新手望而卻步。鐵威馬推出的F8 SSD Plus,以"低門檻+全生態(tài)"為核心理念,不僅讓NAS小白輕松上手,更通過深度適配國產系統(tǒng)生態(tài),...

關鍵字: 鐵威馬 存儲 鐵威馬F8 SSD Plus AI
關閉