• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 新聞中心

    EEPW首頁 > 嵌入式系統(tǒng) > 牛人業(yè)話 > C語言的那些小秘密之堆棧

    C語言的那些小秘密之堆棧

    作者: 時間:2015-03-02 來源:網(wǎng)絡 收藏
    編者按:何為堆棧?首先要明確堆棧是兩種數(shù)據(jù)結(jié)構(gòu)。棧是硬件,堆是一種動態(tài)存儲結(jié)構(gòu),但是它們倆個又是如何共存的呢?  

      明白了上面的內(nèi)容,那么我們就可以實現(xiàn)題目的要求了。代碼如下所示:

    本文引用地址:http://www.czjhyjcfj.com/article/270300.htm

      #include

      using namespace std;

      void print()

      {

      //這里進行排序,print不準傳參數(shù)

     unsigned int _ebp;

     __asm{

      mov _ebp,ebp

      }

      int *p=(int *)(*(int *)_ebp-4-4-4-4-8-7*4);

      for(int i=0;i<7;i++)

      cout<

      }

      int main()

      {

      int s=0;

      int ss=0;

      char *str="fdsafdsafdsafdsafdsafdsafdsa";

      char fdsa='f';

      char srt[8];

      int arr[]={32,43,3,567,987,21,56};//數(shù)值隨即

      print();

      return 0;

      }

      其中用紅色標記的部分是一個重點,用匯編語句mov _ebp,ebp;來獲得ebp寄存器的值,存放在_ebp中,ebp存放當前函數(shù)棧底的地址,就是說ebp可以看做一個指針,指向棧頂,因為 pushl %ebp,所以棧頂存放的數(shù)據(jù)就是上一個函數(shù)的ebp的值,即就是main函數(shù)的棧底。由此可知*(int*)_ebp意思就是取出棧頂?shù)臄?shù)據(jù),即main函數(shù)的棧底。棧中數(shù)據(jù)的存儲方式是根據(jù)聲明的先后順序來的,所以了為了能夠?qū)rr數(shù)組進行打印,我們要計算出數(shù)組首地址的存儲地址,由于變量的壓棧方式默認是四字節(jié)對齊,所以我們使用一句int *p=(int *)(*(int *)_ebp-4-4-4-4-8-7*4);來得到數(shù)組的首地址,有人可能很疑惑了,為什么這句 char *str="fdsafdsafdsafdsafdsafdsafdsa";聲明的變量只是占了四字節(jié)呢?!這里要注意了,因為指針變量的地址在32位的計算機中占用四個字節(jié),他的內(nèi)容并不存儲在棧中,而是在堆中,棧中僅僅是保存了指向堆的指針。講到這兒基本上都豁然開朗了吧。看看下面的運行結(jié)果吧!



      為了強調(diào)默認的字節(jié)對齊概念,我們再來修改下代碼得到的運行結(jié)果可以上面得做一個比較。

      代碼如下,紅色部分為修改代碼。

      #include

      using namespace std;

      void print()

      {

      //這里進行排序,print不準傳參數(shù)

      unsigned int _ebp;

      __asm{

      mov _ebp,ebp

      }

      int *p=(int *)(*(int *)_ebp-4-4-4-4-8-7*4);

      for(int i=0;i<7;i++)

      cout<

      }

      int main()

      {

      int s=0;

      int ss=0;

      char *str="fdsafdsafdsafdsafdsafdsafdsa";

      char fdsa='f';

      char srt[6];

      int arr[]={32,43,3,567,987,21,56};//數(shù)值隨即

      print();

      return 0;

      }

      運行結(jié)果為:



      如果我們修改了 char srt[6];之后去把int *p=(int *)(*(int *)_ebp-4-4-4-4-8-7*4);修改為int *p=(int *)(*(int *)_ebp-4-4-4-4-6-7*4);,注意紅色部分的對比,運行結(jié)果就變?yōu)榱耍?/p>



      顯然對比可知運行結(jié)果出錯了。在此多次一舉的給出對比無非是為了大家能夠?qū)ψ止?jié)的對齊方式加以重視。當然以上內(nèi)容難免有錯,畢竟c語言博大精深,如果有不正確的地方,請糾正。

    c語言相關文章:c語言教程



    上一頁 1 2 下一頁

    關鍵詞: C語言 堆棧

    評論


    相關推薦

    技術專區(qū)

    關閉
    主站蜘蛛池模板: 玛多县| 留坝县| 阳江市| 永福县| 天祝| 德清县| 丹巴县| 河池市| 子洲县| 丘北县| 平利县| 吉安县| 合水县| 景洪市| 邢台县| 潮安县| 虹口区| 达孜县| 丽水市| 南江县| 雅江县| 正镶白旗| 昌平区| 阿荣旗| 镇坪县| 江西省| 肥西县| 阜康市| 达州市| 江西省| 武威市| 景洪市| 凤城市| 南充市| 清水河县| 聊城市| 芷江| 鹤峰县| 梁山县| 昭觉县| 鲁甸县|