新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 匯編技術內幕(5)

        匯編技術內幕(5)

        作者: 時間:2016-11-24 來源:網絡 收藏
        全局變量和全局常量的實驗

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

        本文引用地址:http://www.104case.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,創建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,為局部變量預留棧空間,并保證棧16字節對齊
        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函數返回

        現在,讓我們在全局變量初始化后的地方設置斷點,觀察一下這幾個全局變量的值:
        > main+0x2e:b ; 設置斷點
        > :r ; 運行程序
        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
        >

        概念:進程地址空間 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上的進程地址空間

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

        Kernel總是映射到用戶地址空間的最高端,從宏定義_kernel_base至0xFFFFFFFF的區域
        用戶進程所依賴的各個共享庫緊接著Kernel映射在用戶地址空間的高端
        最后是用戶進程地址空間在地址空間的低端

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

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

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



        關鍵詞: 匯編技

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 宁城县| 克山县| 广元市| 迁西县| 合江县| 永善县| 民和| 基隆市| 玛纳斯县| 讷河市| 嘉定区| 宝山区| 锡林浩特市| 汤原县| 临猗县| 弥渡县| 汕尾市| 丰县| 合水县| 鄱阳县| 万源市| 芮城县| 遂川县| 丽江市| 马公市| 运城市| 肇东市| 兰考县| 北流市| 安康市| 林芝县| 阿瓦提县| 陵水| 隆化县| 遵化市| 禄丰县| 登封市| 广元市| 兴城市| 河东区| 怀集县|