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

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 匯編技術(shù)內(nèi)幕(3)

          匯編技術(shù)內(nèi)幕(3)

          作者: 時(shí)間:2016-11-24 來源:網(wǎng)絡(luò) 收藏
          局部變量棧分配
          下面我們分析一下C編譯器如何處理局部變量的分配,為此先給出如下程序:
          #vi test2.c
          int main()
          {
          int i;
          int j=2;
          i=3;
          i=++i;
          return i+j;
          }
          編譯該程序,產(chǎn)生二進(jìn)制文件,并利用mdb來觀察程序運(yùn)行中的stack的狀態(tài):
          #gcc test2.c -o test2
          #mdb test2
          Loading modules: [ libc.so.1 ]
          > main::dis
          main: pushl %ebp
          main+1: movl %esp,%ebp ; main至main+1,創(chuàng)建Stack Frame
          main+3: subl $8,%esp ; 為局部變量i,j分配棧空間,并保證棧16字節(jié)對(duì)齊
          main+6: andl $0xf0,%esp
          main+9: movl $0,%eax
          main+0xe: subl %eax,%esp ; main+6至main+0xe,再次保證棧16字節(jié)對(duì)齊
          main+0x10: movl $2,-8(%ebp) ; 初始化局部變量j的值為2
          main+0x17: movl $3,-4(%ebp) ; 給局部變量i賦值為3
          main+0x1e: leal -4(%ebp),%eax ; 將局部變量i的地址裝入到EAX寄存器中
          main+0x21: incl (%eax) ; i++
          main+0x23: movl -8(%ebp),%eax ; 將j的值裝入EAX
          main+0x26: addl -4(%ebp),%eax ; i+j并將結(jié)果存入EAX,作為返回值
          main+0x29: leave ; 撤銷Stack Frame
          main+0x2a: ret ; main函數(shù)返回
          >
          通過mdb對(duì)程序運(yùn)行時(shí)的寄存器和棧的觀察和分析,可以得出局部變量在棧中的訪問和分配及釋放方式:
          1.局部變量的分配,可以通過esp減去所需字節(jié)數(shù)
          subl $8,%esp
          2.局部變量的釋放,可以通過leave指令
          leave
          3.局部變量的訪問,可以通過ebp減去偏移量
          movl -8(%ebp),%eax
          addl -4(%ebp),%eax
          問題:當(dāng)存在2個(gè)以上的局部變量時(shí),如何進(jìn)行棧對(duì)齊?
          在上篇文章中,提到subl $8,%esp語句除了分配??臻g外,還有一個(gè)作用就是棧對(duì)齊。那么本例中,由于i和j正好是8字節(jié),那么如果存在2個(gè)以上的局部變量時(shí),如何同時(shí)滿足空間分配和棧對(duì)齊呢?


          評(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); })();