<acronym id="xonnx"></acronym>
      <td id="xonnx"></td>
    1. <pre id="xonnx"></pre>

      1. 專注電子技術學習與研究
        當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

        堆棧的深入個人理解

        作者:wupingping   來源:wupingping   點擊數:  更新時間:2014年06月21日   【字體:
        對于,,堆棧的味道,一直就跟豬八戒吃啥來著,從沒有細細地品嘗過。發了下狠心,各個網頁看了很多,這里就把我東抓西拼的東西整理整理。
         
        一  這些個概念怎么來的以及怎么記得住
        這里,只限于整理我個人對堆/棧/堆棧在內存管理方面的理解。其他,在數據結構方面講的堆/棧目前不在我整理范圍之內。
        這里提了三個概念: 堆,棧,以及堆棧。我把堆棧的概念等同了。所以,接下來只要把兩個概念弄清楚就可以了:。
         
        先說由來。由于我的工作大部分是和單片機相關的,因此也是基于嵌入式的這個方面的理解。
        每片MCU有一定的內存,這些內存分:程序存儲區;數據存儲區。舉例就是:我們寫的每行代碼,都會保存到程序存儲區里面;而定義的一些全局變量,靜態變量,局部變量之類的,就保存到數據存儲區。
        程序存儲區,對于寫代碼的人來說,可以說是黑盒子:只要你的代碼不超過程序代碼空間,everything will be fine. 代碼究竟是如何執行的,取決于你的編程思想,就是說,你讓程序往東走,它就會往東走;讓它原地踏步,它也會照做;前提是你的代碼要寫好。所以,對于編程經驗成熟的人,同樣的算法,他可能會少敲幾行代碼,并且算法出錯的幾率少一些;不怎么會編程的人,就多敲幾行,多測試一下。研究深一些的人,可能還會對代碼執行效率深入研究。我決定就此止步。繼續黑盒子的話題,程序員的代碼會燒寫到程序存儲區里面,至于哪條語句存哪里,這個是不用研究的。反正,一旦發現軟件沒按照你設計的那樣跑,基本就是程序自身的問題,不是存放程序的存儲區的問題。
        數據存儲區,讓程序員發揮的空間就很大了。由于程序是動態地執行的,執行的結果是怎么樣,會產生什么數據就不是一個確定的事情。
        舉個例子說說這個程序和數據之間的表象吧。舉例的事件就是:一個MP3播放器的上/下鍵的操作。加入在播放器里有10首歌,若當前是第3首,那么按下[上]鍵后,應該是播放第2首。因此,實現播放第2首的,就是程序員寫程序實現的,他的代碼讓[上]鍵實現了能從第3首切換到第2首的操作。這里,表現的就是代碼。而且,這個代碼是確切的行為,從第3首按了[上]鍵之后,一定是播放到第2首。這個是確切的行為,如果不能實現,就是代碼有bug了,需要改正。終于可以扯到數據了。第2首是什么歌呢? 就是說第2首歌的內容是什么呢? 當然在程序員寫代碼的時候,他是不知道的,他要做的,就是預先開一片數據空間,以存放歌曲相關的數據。這片數據空間,想放什么就放什么,是靈活的。聽煩了這幾首歌以后,再更換其它音頻文件就是了。再說具體一點,程序就相當于修的一條路,讓車可以在上面跑;但車上面裝了什么,程序員是不知道的。
         
        女人就是啰嗦啊。女人的話題也是可以轉得很快的。
        屬于數據存儲區的范疇,也可以算是數據管理的手段或方法;诖,不能一概而論,說哪個手段高明一些;他們也是基于現實的需要而產生的。黑格爾說:存在就是合理的。
        這樣的概念大家都不陌生:軍隊的管理是很嚴格的,很死板的;但是對于一些年輕的技術公司來說,員工就享有很高的自由度。
        如果我說,墻角邊整齊地擺放著10本書; 以及墻角邊的書凌亂地放著。你閉上眼睛,能區分出兩種畫面嗎? 如果沒有,就不用往下看了。
        棧的特性,就是嚴格/有序/規范的。棧的英文就是Stack. 如果我說,there are books stacked in that corner,你應該能知道書是怎么放的吧。
        相反,堆呢,就是自由/靈活/隨意的。堆的英文是Heap. 如果我說,there are books heaped in that corner,你應該能知道書是怎么放的吧。 
         
        二  get closer to the real STACK/HEAP。
        : 由系統自動分配和回收的。
        : 由程序員分配和回收的。
        基于第一部分的理解,不用想都知道,作為“堆”的數據空間,也必須是靈活的,因為成千上萬的程序員在寫什么程序是未知的。但可知道的一點,就是他們是跑在確定的某個OS里面的。
        因此,也不過就是給系統管理的數據空間起了個名字,就;給程序員使用的空間,起了個名,就。
        我接下來就會廢話:起什么名字都不重要,重要的是,我們得對這兩種數據存儲區的管理的機制由來,方法有深刻認識;這樣,即便幾個世紀以后它們更名為阿貓阿狗了,我們依然能認知它們。
         
        舉例: 
        void Check_Pro_Code( uint8  style )
        {
             uint8 i;
         
             switch( style )
             {
              ......
             }
        }
         
        void main( )
        {
             uint8 j = 1;
             
             Check_Pro_Code( j );              
        }
         
        在main()函數里調用了Check_Pro_Code(...)函數,事先要對j進行入棧操作;當然這里函數調用的時候,涉及到幾個入棧操作:程序的下一個執行地址;局部變量;形參。
        這里,我就沒有深入介紹了。
         
        實在很慚愧的是,我寫的嵌入式軟件里,沒有涉及到任何和操作相關的。我就是那樣一個人,CM3內核里也沒有移植操作系統,實在是汗顏,因為本人對RTOS實在是未曾涉獵。所以,我這里對于堆的介紹,是沒有任何實戰鷹眼的。并且為了我就了一下。你說,這樣算學術造假嗎?
        void main( )
        {
        int j=10;
        int *p;
         
        p = "123456".
        }

        三  話說堆棧溢出
        再次明確,堆棧溢出堆棧是指。
        1  當C程序函數的調用層次過深或者出現了遞歸調用,就容易使程序運行所需的堆?臻g超過系統能提供的最大堆?臻g范圍,產生堆棧溢出。
        這是很明白的,當A函數調用了B函數,而B()里面又調用了C(),C()里又調用了D()......當這樣的調用太深的時候,就容易堆棧溢出了。  
         
        四   一級緩存/二級緩存
        棧使用的是一級緩存, 他們通常都是被調用時處于存儲空間中,調用完畢立即釋放。
        堆則是存放在二級緩存中,生命周期由虛擬機的垃圾回收算法來決定(并不是一旦成為孤兒對象就能被回收)。所以調用這些對象的速度要相對來得低一些。
        棧的優勢是,存取速度比堆要快,僅次于直接位于CPU中的寄存器。
        舉個我知道的例子: 
        void main( )
        {
        int i,j;
        static int flag = 1;
         
        i = Sum_Of_Group( );     
        j = Check_Exist( );
        }
        這里,i,j的值都是給通用寄存器的,而不是給予確切的物理地址。而對于flag,由于其為靜態變量,是在SRAM里面分配地址的。這里好像沒有說到一級緩存二級緩存。時間限制,下回述。
         
        五  :在Windows下,棧是向低地址擴展的數據結構,是一塊連續的內存的區域。這句話的意思是棧頂的地址和棧的最大容量是系統預先規定好的,在 WINDOWS下,棧的大小是2M(也有的說是1M,總之是一個編譯時就確定的常數),如果申請的空間超過棧的剩余空間時,將提示overflow。因此,能從棧獲得的空間較小。
        :堆是向高地址擴展的數據結構,是不連續的內存區域。這是由于系統是用鏈表來存儲的空閑內存地址的,自然是不連續的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限于計算機系統中有效的虛擬內存。由此可見,堆獲得的空間比較靈活,也比較大。
        注:該段內容100%抄襲,出處:網絡。 
         
        六  如何修改我自己的工程的STACK(以下內容不通用)
        由于我自己的工程用的是LPC1765,剛好從網絡抄到了比較有用的圖片。摘于此。其他單片機的編譯環境,應該也是差不多如法炮制的。
        編譯環境: IAR for ARM.
        圖一  :如何修改STACK的大小
         
               
         圖二,如何知道自己的工程用了多少堆棧
         

         
         
         
        整理了2個小時,僅以此文,紀念我美好生活的另一種開始。
         
         
         
         
         
        關閉窗口

        相關文章

        欧美性色欧美精品视频,99热这里只有精品mp4,日韩高清亚洲日韩精品一区二区,2020国自产拍精品高潮