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

          新聞中心

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

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

          作者: 時(shí)間:2016-11-24 來(lái)源:網(wǎng)絡(luò) 收藏
          全局變量和全局常量的實(shí)驗(yàn)

          延續(xù)之前的方式,給出一個(gè)簡(jiǎn)單的C程序,其中聲明的全局變量分為3種:
          初始化過(guò)的全局變量
          未初始化的全局變量
          全局常量
          #vi test5.c

          本文引用地址:http://www.ex-cimer.com/article/201611/320805.htm

          int i=1;
          int j=2;
          int k=3;
          int l,m;
          int n;
          const int o=7;
          const int p=8;
          const int q=9;
          int main()
          {
          l=4;
          m=5;
          n=6;
          return i+j+k+l+m+n+o+p+q;
          }
          # gcc test5.c -o test5
          # mdb test5
          Loading modules: [ libc.so.1 ]
          > main::dis
          main: pushl %ebp ; main至main+1,創(chuàng)建Stack Frame
          main+1: movl %esp,%ebp
          main+3: subl $8,%esp
          main+6: andl $0xf0,%esp
          main+9: movl $0,%eax
          main+0xe: subl %eax,%esp ; main+3至main+0xe,為局部變量預(yù)留??臻g,并保證棧16字節(jié)對(duì)齊
          main+0x10: movl $4,0x8060948 ; l=4
          main+0x1a: movl $5,0x806094c ; m=5
          main+0x24: movl $6,0x8060950 ; n=6
          main+0x2e: movl 0x8060908,%eax
          main+0x33: addl 0x8060904,%eax
          main+0x39: addl 0x806090c,%eax
          main+0x3f: addl 0x8060948,%eax
          main+0x45: addl 0x806094c,%eax
          main+0x4b: addl 0x8060950,%eax
          main+0x51: addl 0x8050808,%eax
          main+0x57: addl 0x805080c,%eax
          main+0x5d: addl 0x8050810,%eax ; main+0x2e至main+0x5d,i+j+k+l+m+n+o+p+q
          main+0x63: leave ; 撤銷Stack Frame
          main+0x64: ret ; main函數(shù)返回

          現(xiàn)在,讓我們?cè)谌肿兞砍跏蓟蟮牡胤皆O(shè)置斷點(diǎn),觀察一下這幾個(gè)全局變量的值:
          > main+0x2e:b ; 設(shè)置斷點(diǎn)
          > :r ; 運(yùn)行程序
          mdb: stop at main+0x2e
          mdb: target stopped at:
          main+0x2e: movl 0x8060908,%eax
          > 0x8060904,03/nap ; 察看全局變量 i,j,k的值
          test5`i:
          test5`i:
          test5`i: 1
          test5`j: 2
          test5`k: 3
          > 0x8060948,03/nap ; 察看全局變量l,m,n的值
          test5`l:
          test5`l:
          test5`l: 4
          test5`m: 5
          test5`n: 6
          > 0x8050808,03/nap ; 察看全局變量o,p,q的值
          o:
          o:
          o: 7
          p: 8
          q: 9
          >

          概念:進(jìn)程地址空間 Process Address Space

          +----------------------+ ----> 0xFFFFFFFF (4GB)
          | |
          | Kernel Space |
          | |
          +----------------------+ ----> _kernel_base (0xE0000000)
          | |
          | Other Library |
          : :
          : :
          | |
          +----------------------+
          | data section |
          | Lib C Library |
          | text section |
          : :
          : :
          +----------------------+
          | |
          | |
          : :
          : grow up :
          : :
          | User Heap |
          | |
          +----------------------+
          | bss |
          | |
          | User Data |
          | |
          +----------------------+
          | |
          | User Text |
          | |
          | |
          +----------------------+ ----> 0x08050000
          | |
          | User Stack |
          | |
          : grow down :
          : :
          : :
          | |
          | |
          +----------------------+ ----> 0

          圖 3-1 Solaris在IA32上的進(jìn)程地址空間

          如圖3-1所示,Solaris在IA32上的進(jìn)程地址空間和Linux是相似的,在用戶進(jìn)程的4GB地址空間內(nèi):

          Kernel總是映射到用戶地址空間的最高端,從宏定義_kernel_base至0xFFFFFFFF的區(qū)域
          用戶進(jìn)程所依賴的各個(gè)共享庫(kù)緊接著Kernel映射在用戶地址空間的高端
          最后是用戶進(jìn)程地址空間在地址空間的低端

          各共享庫(kù)的代碼段,存放著二進(jìn)制可執(zhí)行的機(jī)器指令,是由kernel把該庫(kù)ELF文件的代碼段map到虛存空間,屬性是read/exec/share
          各共享庫(kù)的數(shù)據(jù)段,存放著程序執(zhí)行所需的全局變量,是由kernel把ELF文件的數(shù)據(jù)段map到虛存空間,屬性為read/write/private
          用戶代碼段,存放著二進(jìn)制形式的可執(zhí)行的機(jī)器指令,是由kernel把ELF文件的代碼段map到虛存空間,屬性為read/exec
          用戶代碼段之上是數(shù)據(jù)段,存放著程序執(zhí)行所需的全局變量,是由kernel把ELF文件的數(shù)據(jù)段map到虛存空間,屬性為 read/write/private
          用戶代碼段之下是棧(stack),作為進(jìn)程的臨時(shí)數(shù)據(jù)區(qū),是由kernel把匿名內(nèi)存map到虛存空間,屬性為read/write/exec
          用戶數(shù)據(jù)段之上是堆(heap),當(dāng)且僅當(dāng)malloc調(diào)用時(shí)存在,是由kernel把匿名內(nèi)存map到虛存空間,屬性為read/write/exec

          注意Stack和Heap的區(qū)別和聯(lián)系:
          相同點(diǎn):
          1. 都是來(lái)自于kernel分配的匿名內(nèi)存,和磁盤上的ELF文件無(wú)關(guān)
          2. 屬性均為read/write/exec
          不同點(diǎn):
          1.棧的分配在C語(yǔ)言層面一般是通過(guò)聲明局部變量,調(diào)用函數(shù)引起的;堆的分配則是通過(guò)顯式的調(diào)用(malloc)引起的
          2.棧的釋放在C語(yǔ)言層面是對(duì)用戶透明的,用戶不需要關(guān)心,由C編譯器產(chǎn)生的相應(yīng)的指令代勞;堆則需顯式的調(diào)用(free)來(lái)釋放
          3.棧空間的增長(zhǎng)方向是從高地址到低地址;堆空間的增長(zhǎng)方向是由低地址到高地址
          4.棧存在于任何進(jìn)程的地址空間;堆則在程序中沒(méi)有調(diào)用malloc的情況下不存在

          用戶地址空間的布局隨著CPU和OS的不同,略有差異,以上都是基于X86 CPU在Solaris OS上的情況的討論。



          關(guān)鍵詞: 匯編技

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