1. <var id="fe6gj"></var>

    <rp id="fe6gj"><nav id="fe6gj"></nav></rp>

    <noframes id="fe6gj"><cite id="fe6gj"></cite>

    <ins id="fe6gj"><button id="fe6gj"><p id="fe6gj"></p></button></ins>
    1. <tt id="fe6gj"><i id="fe6gj"><sub id="fe6gj"></sub></i></tt>
        始創于2000年 股票代碼:831685
        咨詢熱線:0371-60135900 注冊有禮 登錄
        • 掛牌上市企業
        • 60秒人工響應
        • 99.99%連通率
        • 7*24h人工
        • 故障100倍補償
        您的位置: 網站首頁 > 幫助中心>文章內容

        深入理解Linux內存映射機制 (4)

        發布時間:  2012/8/15 18:19:51

        84 84 04 08 push $0x8048484
        8048376: e8 35 ff ff ff call 80482b0 <printf@plt>
        804837b: 83 c4 10 add $0x10,%esp
        804837e: c9 leave
        804837f: c3 ret

        08048380 <main>:
        8048380: 55 push %ebp
        8048381: 89 e5 mov %esp,%ebp
        8048383: 83 ec 08 sub $0x8,%esp
        8048386: 83 e4 f0 and $0xfffffff0,%esp
        8048389: b8 00 00 00 00 mov $0x0,%eax
        804838e: 83 c0 0f add $0xf,%eax
        8048391: 83 c0 0f add $0xf,%eax
        8048394: c1 e8 04 shr $0x4,%eax
        8048397: c1 e0 04 shl $0x4,%eax
        804839a: 29 c4 sub %eax,%esp
        804839c: e8 c7 ff ff ff call 8048368 <test>
        80483a1: c9 leave
        80483a2: c3 ret
        80483a3: 90 nop
        從上述結果可以看到, ld給test()函數分配的地址為0x08048368.在elf格式的可執行文件代碼中,ld的實際位置總是從0x8000000開始安排程序的代碼段, 對每個程序都是這樣。至于程序在執行時在物理內存中的實際位置就要由內核在為其建立內存映射時臨時做出安排, 具體地址則取決于當時所分配到的物理內存頁面。假設該程序已經運行, 整個映射機制都已經建立好, 并且CPU正在執行main()中的call 8048368這條指令, 要轉移到虛擬地址0x08048368去運行. 下面將詳細介紹這個虛擬地址轉換為物理地址的映射過程.
        首先是段式映射階段。由于0x08048368是一個程序的入口,更重要的是在執行的過程中是由CPU中的指令計數器EIP所指向的, 所以在代碼段中。 因此, i386CPU使用代碼段寄存器CS的當前值作為段式映射的選擇子, 也就是用它作為在段描述表的下標.那么CS的值是多少呢?
        用GDB調試下test:
        (gdb) info reg
        eax 0x10 16
        ecx 0x1 1
        edx 0x9d915c 10326364
        ebx 0x9d6ff4 10317812
        esp 0xbfedb480 0xbfedb480
        ebp 0xbfedb488 0xbfedb488
        esi 0xbfedb534 -1074940620
        edi 0xbfedb4c0 -1074940736
        eip 0x804836e 0x804836e
        eflags 0x282 642
        cs 0x73 115
        ss 0x7b 123
        ds 0x7b 123
        es 0x7b 123
        fs 0x0 0
        gs 0x33 51
        可以看到CS的值為0x73, 我們把它分解成二進制:
        0000 0000 0111 0011
        最低2位為3, 說明RPL的值為3, 應為我們這個程序本省就是在用戶空間,RPL的值自然為3.
        第3位為0表示這個下標在GDT中。
        高13位為14, 所以段描述符在GDT表的第14個表項中, 我們可以到內核代碼中去驗證下:
        在i386/asm/segment.h中:
        #define GDT_ENTRY_DEFAULT_USER_CS 14
        #define __USER_CS (GDT_ENTRY_DEFAULT_USER_CS * 8 3)
        可以看到段描述符的確就是GDT表的第14個表項中。
        我們去GDT表看看具體的表項值是什么, GDT的內容在arch/i386/kernel/head.S中定義:
        ENTRY(cpu_gdt_table)
        .quad 0x0000000000000000 /* NULL descriptor */
        .quad 0x0000000000000000 /* 0x0b reserved */
        .quad 0x0000000000000000 /* 0x13 reserved */
        .quad 0x0000000000000000 /* 0x1b reserved */
        .quad 0x0000000000000000 /* 0x20 unused */
        .quad 0x0000000000000000 /* 0x28 unused */
        .quad 0x0000000000000000 /* 0x33 TLS entry 1 */
        .quad 0x0000000000000000 /* 0x3b TLS entry 2 */
        .quad 0x0000000000000000 /* 0x43 TLS entry 3 */
        .quad 0x0000000000000000 /* 0x4b reserved */
        .quad 0x0000000000000000 /* 0x53 reserved */
        .quad 0x0000000000000000 /* 0x5b reserved */

        .quad 0x00cf9a000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
        .quad 0x00cf92000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
        .quad 0x00cffa000000ffff /* 0x73 user 4GB code at 0x00000000 */
        .quad 0x00cff2000000ffff /* 0x7b user 4GB data at 0x00000000 */
        .quad 0x0000000000000000 /* 0x80 TSS descriptor */
        .quad 0x0000000000000000 /* 0x88 LDT descriptor */

        /* Segments used for calling PnP BIOS */
        .quad 0x00c09a0000000000 /* 0x90 32-bit code */
        .quad 0x00809a0000000000 /* 0x98 16-bit code */
        .quad 0x0080920000000000 /* 0xa0 16-bit data */
        .quad 0x0080920000000000 /* 0xa8 16-bit data */
        .quad 0x0080920000000000 /* 0xb0 16-bit data */
        /*
        * The APM segments have byte granularity and their bases
        * and limits are set at run time.
        */
        .quad 0x00409a0000000000 /* 0xb8 APM CS code */
        .quad 0x00009a0000000000 /* 0xc0 APM CS 16 code (16 bit) */
        .quad 0x0040920000000000 /* 0xc8 APM DS data */

        .quad 0x0000000000000000 /* 0xd0 - unused */
        .quad 0x0000000000000000 /* 0xd8 - unused */
        .quad 0x0000000000000000 /* 0xe0 - unused */
        .quad 0x0000000000000000 /* 0xe8 - unused */
        .quad 0x0000000000000000 /* 0xf0 - unused */
        .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
        .quad 0x00cffa000000ffff /* 0x73 user 4GB code at 0x00000000 */

        我們把這個值展開成二進制:
        0000 0000 1100 1111 1111 1010 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111
        根據上述對段描述符表項值的描述, 可以得出如下結論:
        B0-B15, B16-B31是0, 表示基地址全為0.
        L0-L15, L16-L19是1, 表示段的上限全是0xffff.
        G位是1 表示段長度單位均為4KB。
        D位是1 表示對段的訪問都是32位指令
        P位是1 表示段在內存中。
        DPL是3 表示特權級是3級
        S位是1 表示為代碼段或數據段
        type為1010 表示代碼段, 可讀, 可執行, 尚未收到訪問
        這個描述符指示了段從0地址開始的整個4G虛存空間,邏輯地址直接轉換為線性地址。
        所以在經過段式映射后就把邏輯地址轉換成了線性地址, 這也是在linux中, 為什么邏輯地址等同于線性地址的原因了。
        4.3 頁式映射

        億恩科技地址(ADD):鄭州市黃河路129號天一大廈608室 郵編(ZIP):450008 傳真(FAX):0371-60123888
           聯系:億恩小凡
           QQ:89317007
           電話:0371-63322206


        本文出自:億恩科技【www.endtimedelusion.com】

        服務器租用/服務器托管中國五強!虛擬主機域名注冊頂級提供商!15年品質保障!--億恩科技[ENKJ.COM]

      1. 您可能在找
      2. 億恩北京公司:
      3. 經營性ICP/ISP證:京B2-20150015
      4. 億恩鄭州公司:
      5. 經營性ICP/ISP/IDC證:豫B1.B2-20060070
      6. 億恩南昌公司:
      7. 經營性ICP/ISP證:贛B2-20080012
      8. 服務器/云主機 24小時售后服務電話:0371-60135900
      9. 虛擬主機/智能建站 24小時售后服務電話:0371-60135900
      10. 專注服務器托管17年
        掃掃關注-微信公眾號
        0371-60135900
        Copyright© 1999-2019 ENKJ All Rights Reserved 億恩科技 版權所有  地址:鄭州市高新區翠竹街1號總部企業基地億恩大廈  法律顧問:河南亞太人律師事務所郝建鋒、杜慧月律師   京公網安備41019702002023號
          0
         
         
         
         

        0371-60135900
        7*24小時客服服務熱線

         
         
        av不卡不卡在线观看_最近2018年中文字幕_亚洲欧美一区二区三区_一级A爱做片免费观看国产_日韩在线中文天天更新_伊人中文无码在线