<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > Keil C51內(nèi)存分配與優(yōu)化

          Keil C51內(nèi)存分配與優(yōu)化

          作者: 時(shí)間:2016-11-28 來(lái)源:網(wǎng)絡(luò) 收藏

          obj(lib)文件然后經(jīng)過(guò)l51.exe(bl51.exe),就是說(shuō)把可執(zhí)行代碼模塊根據(jù)連接定位參數(shù)地址上連接在一起();數(shù)據(jù)段也連接在 一起,在ram空間中分配.對(duì)ram空間的分配中就有一個(gè)連接過(guò)程"覆蓋分析".調(diào)用一個(gè)c函數(shù),就會(huì)為這個(gè)函數(shù)所使用的ram空間進(jìn)行分配(一些局部變 量),這個(gè)函數(shù)返回時(shí)再回收分配給他的ram空間,根據(jù)函數(shù)互相之間的調(diào)用前后關(guān)系,編譯器就可以時(shí)實(shí)的知道ram空間的使用情況(其中就存在一個(gè)函數(shù)重 入的問(wèn)題),作為連接時(shí)ram空間分配的參數(shù). 如果源文件中的函數(shù)(模塊)從來(lái)沒(méi)有被任何函數(shù)顯示的調(diào)用(所謂非顯示調(diào)用就是這段代碼,連接器目前還不知道這段代碼什么時(shí)候會(huì)被調(diào)用或是否會(huì)被調(diào)用), 連接時(shí)就會(huì)為它分配永遠(yuǎn)有效的ram空間(就象全局變量),不會(huì)被回收。

          (http://blog.sina.com.cn/s/blog_74ee88b80100pqed.html)

          *******************************************************************

          //程序6

          #include

          #define uint unsigned int

          #define uchar unsigned char

          uchar a;

          uint b;

          uint sum2(uint e,uint f,uint g,uint j)

          {

          uint i;

          i = e+f+g+j;

          return i;

          }

          void main()

          {

          b = sum2(1,2,3,4);

          }

          Program Size: data=20.0 xdata=0 code=58

          TYPEBASELENGTHRELOCATIONSEGMENT NAME

          -----------------------------------------------------

          * * * * * * *D A T AM E M O R Y* * * * * * *

          REG0000H0008HABSOLUTE"REG BANK 0"

          DATA0008H0008HUNIT_DATA_GROUP_

          DATA0010H0003HUNIT?DT?MAIN

          IDATA0013H0001HUNIT?STACK

          **************************************************************

          在上面的程序中如果將sum2中的j去掉,那么data = 12.0。

          通過(guò)程序5和6可以看到,兩個(gè)程序的M51文件中的藍(lán)色部分的segement name的名稱有很大的區(qū)別。_DATA_GROUP_是一個(gè)OVERALY GROUPS(覆蓋組)。它是鏈接器產(chǎn)生的可覆蓋的一個(gè)數(shù)據(jù)段。而上面的程序5中的?DT?_SUM?MAIN,則是一個(gè)函數(shù)段。

          在Keil中對(duì)OVERALY GROUPS的解釋為:

          When performing overlay analysis, the linker creates groups of segments that are overlaid. The group name indicates the memory type of the variables that it includes.

          Group Name

          Segment
          Prefix

          Memory
          Model

          Description

          _BIT_GROUP_

          ?BI?

          All

          Variables and arguments of typebit.

          _DATA_GROUP_

          ?DT?

          SMALL

          Variables and arguments other thanbit.

          _PDATA_GROUP_

          ?PD?

          COMPACT

          Variables and arguments other thanbit.

          _XDATA_GROUP_

          ?XD?

          LARGE

          Variables and arguments other thanbit.

          When the linker overlays function data memory and creates a group, that groups appears in the linker map files memory map section.

          STARTSTOPLENGTHALIGNRELOCMEMORY CLASSSEGMENT NAME
          ======================================================================
          * * * * * * * * * * *D A T AM E M O R Y* * * * * * * * * * * * *
          000000H000007H000008H---AT..DATA"REG BANK 0"
          000008H00001AH000013HBYTEUNITDATA_DATA_GROUP_
          00001BH00001BH000001HBYTEUNITIDATA?STACK

          Groups are created based on the memory model of the function (which specifies the memory class where parameters and variables are stored) and on any variables defined with a specific memory space.

          在keil生成的M51函數(shù)中有OVERLAY MAP OF MODULE,對(duì)程序中函數(shù)調(diào)用的覆蓋有詳細(xì)的說(shuō)明。

          //程序7

          #define LEN 120
          data uchar tt1[LEN];
          idata uchar tt2[127];

          void main()
          {
          uchar i,j;

          for(i = 0;i < LEN; ++i )
          {
          j = i;
          tt1[j] = 0x55;
          }
          }

          變量i和j通過(guò)編譯器的優(yōu)化占用了通用寄存器,R0-8[8]+tt1[120]+tt2[127]+SP[1]共256字節(jié);

          而如果將程序7中j=i刪掉。上面聲明了uchar j,但是下面沒(méi)有應(yīng)用,因此編譯器不知道該如何處理j,就讓其占用了一個(gè)RAM空間不再存在通用寄存器中,出現(xiàn)了內(nèi)存溢出。(有的編譯器會(huì)將不用的變量自動(dòng)刪除)

          局部變量占用通用寄存器,變量在聲明時(shí)就被分配了空間;局部變量只有在被聲明、賦值且被使用后才認(rèn)為是局部變量被放置在通用寄存器中,否則被認(rèn)為是全局變量;在循環(huán)中,R7中放置循環(huán)數(shù)。(自加)

          由于data區(qū)的存取速度快,變量盡量的放在該區(qū),但是由于idata可以訪問(wèn)整個(gè)256字節(jié)的RAM,如果data區(qū)變量較少,idata型的變量也會(huì)占有data區(qū),減少了可直接訪問(wèn)的存儲(chǔ)空間,因此在變量定義的時(shí)候盡量將idata型的變量定義在data型變量后。

          uchar c1;
          idata uchar c2;
          uchar c3;
          變量 c2 肯定會(huì)以間接尋址,但它有可能落在 data 區(qū)域,就浪費(fèi)了一個(gè)可直接尋址的空間

          變量的優(yōu)化

          (http://weimenlove.blog.163.com/blog/static/177754732009418105322546/)

          (1)將訪問(wèn)頻率高的變量放在data區(qū)

          (2)提高內(nèi)存的復(fù)用率。盡可能的利用局部變量,由于局部變量的存取速度快。在程序7中可以看到,i和j沒(méi)有占用內(nèi)存,子程序中使用內(nèi)存數(shù)量不大的變量盡量定義為局部變量。

          (3)對(duì)于指針數(shù)組的定義,盡量指明存儲(chǔ)類型。盡量使用無(wú)符號(hào)類型變量。8051不支持有符號(hào)數(shù)計(jì)算,需要通過(guò)其他的庫(kù)來(lái)處理,大大降低了運(yùn)行的速度,增加了內(nèi)存的利用。

          (4)避免出現(xiàn)內(nèi)存空洞。在M51中可以很清楚的看到內(nèi)存的分配情況,如果全局變量和局部變量的分配不合理,有時(shí)會(huì)出現(xiàn)下面的情況:

          0010H0012H*** GAP ***

          表示從0010開(kāi)始有0012H個(gè)字節(jié)未利用。造成這種情況的原因是局變量太多、多個(gè)子程序中的局部變量數(shù)目差異太大、使用了寄存器切換但未充分利用

          (5)避免出現(xiàn)未使用的變量或者函數(shù)。


          上一頁(yè) 1 2 下一頁(yè)

          關(guān)鍵詞: KeilC51內(nèi)存分

          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();