日本a√视频在线,久久青青亚洲国产,亚洲一区欧美二区,免费g片在线观看网站

        <style id="k3y6c"><u id="k3y6c"></u></style>
        <s id="k3y6c"></s>
        <mark id="k3y6c"></mark>
          
          

          <mark id="k3y6c"></mark>

          新聞中心

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

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

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

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

          本文引用地址:http://yuyingmama.com.cn/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è)共享庫緊接著Kernel映射在用戶地址空間的高端
          最后是用戶進(jìn)程地址空間在地址空間的低端

          各共享庫的代碼段,存放著二進(jìn)制可執(zhí)行的機(jī)器指令,是由kernel把該庫ELF文件的代碼段map到虛存空間,屬性是read/exec/share
          各共享庫的數(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. 都是來自于kernel分配的匿名內(nèi)存,和磁盤上的ELF文件無關(guān)
          2. 屬性均為read/write/exec
          不同點(diǎn):
          1.棧的分配在C語言層面一般是通過聲明局部變量,調(diào)用函數(shù)引起的;堆的分配則是通過顯式的調(diào)用(malloc)引起的
          2.棧的釋放在C語言層面是對(duì)用戶透明的,用戶不需要關(guān)心,由C編譯器產(chǎn)生的相應(yīng)的指令代勞;堆則需顯式的調(diào)用(free)來釋放
          3.??臻g的增長方向是從高地址到低地址;堆空間的增長方向是由低地址到高地址
          4.棧存在于任何進(jìn)程的地址空間;堆則在程序中沒有調(diào)用malloc的情況下不存在

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



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

          評(píng)論


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

          關(guān)閉