<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    軟件是對質(zhì)量的不懈追求

    進(jìn)程的地址空間

    一個程序經(jīng)過編譯連接后形成的地址空間是一個虛擬地址空間,而Linux在內(nèi)存尋址時簡化了分段
    機制,使得虛擬地址與線性地址是一致的,比如程序test_wait.c代碼如下:
        #include <stdio.h>
        #include 
    <stdlib.h>                                                                                          
        #include 
    <unistd.h>
        
    int main(int argc, char **argv)
        {
                
    int i;
                unsigned 
    char *buff;
                buff 
    = (char *)malloc(sizeof(char)*1024);
                printf(
    "pid is :%d\n", getpid());
               
    for (i = 0; i < 60; i++) {
                       sleep(
    60);
               }  
               
    return 0;
       }
    經(jīng)過編譯后形成的文件是test_wait,然后用命令objdump反匯編后如下(只取部分代碼):

    $ objdump -d test_wait
    test_wait:     file format elf32-i386
    Disassembly of section .init:
    08048304 <_init>:
     8048304:   55                       push   %ebp
     8048305:   89 e5                    mov    %esp,%ebp
     8048307:   53                       push   %ebx
     8048308:   83 ec 04                 sub    $0x4,%esp
     804830b:   e8 00 00 00 00           call   8048310 <_init+0xc>
     8048310:   5b                       pop    %ebx
     8048311:   81 c3 e4 1c 00 00        add    $0x1ce4,%ebx
     8048317:   8b 93 fc ff ff ff        mov    -0x4(%ebx),%edx
     804831d:   85 d2                    test   %edx,%edx
     8048301:   e8 2e 00 00 00           call   8048334 <__gmon_start__@plt>
     8048306:   e8 15 01 00 00           call   8048420

    可以看到,其中的地址就是虛擬地址,整個虛擬地址空間大小為3GB,再加上可以通過系統(tǒng)調(diào)用進(jìn)入
    內(nèi)核的1GB空間,于是每個進(jìn)程可以擁有4GB的虛擬地址空間(也叫虛擬內(nèi)存)。某個進(jìn)程的虛擬地
    址空間可以通過/proc文件系統(tǒng)看到:
    $ ./test_wait
    pid is :9840
    重新開一個終端:

    cat /proc/9840/maps
    08048000-08049000 r-xp 00000000 08:01 212891     /home/chen/mem/test_wait
    08049000-0804a000 r--p 00000000 08:01 212891     /home/chen/mem/test_wait
    0804a000-0804b000 rw-p 00001000 08:01 212891     /home/chen/mem/test_wait
    096d5000-096f6000 rw-p 096d5000 00:00 0          [heap]
    b7dee000-b7def000 rw-p b7dee000 00:00 0
    b7def000-b7f47000 r-xp 00000000 08:01 409724     /lib/tls/i686/cmov/libc-2.8.90.so
    b7f47000-b7f49000 r--p 00158000 08:01 409724     /lib/tls/i686/cmov/libc-2.8.90.so
    b7f49000-b7f4a000 rw-p 0015a000 08:01 409724     /lib/tls/i686/cmov/libc-2.8.90.so
    b7f4a000-b7f4d000 rw-p b7f4a000 00:00 0
    b7f59000-b7f5c000 rw-p b7f59000 00:00 0
    b7f5c000-b7f76000 r-xp 00000000 08:01 392460     /lib/ld-2.8.90.so
    b7f76000-b7f77000 r-xp b7f76000 00:00 0          [vdso]
    b7f77000-b7f78000 r--p 0001a000 08:01 392460     /lib/ld-2.8.90.so
    b7f78000-b7f79000 rw-p 0001b000 08:01 392460     /lib/ld-2.8.90.so
    bf964000-bf979000 rw-p bffeb000 00:00 0          [stack]

    關(guān)于此文件的詳細(xì)信息可以參看:
    http://www.kerneltravel.net/?p=287
    由上面的信息可以看到
    08048000-08049000地址段的標(biāo)志是r-xp(讀,執(zhí)行)是代碼段,
    08049000-0804a000的標(biāo)志是rw-p(讀寫)是數(shù)據(jù)段
    096d5000-096f6000是堆也叫空洞,只有當(dāng)程序中調(diào)用malloc()申請空間時才有堆段。
    bf964000-bf979000 是堆棧段
    這樣我們可以看到進(jìn)程的用戶空間的分配了。如下圖:
     
     

    可以看出代碼段在最低地址依次往上是數(shù)據(jù)段,空洞、堆棧段在最高地址,棧指針向下移動。
    進(jìn)程的虛擬地址在保存在內(nèi)核中的task_struct(PCB)結(jié)構(gòu)中,定義如下:
    struct task_struct { //進(jìn)程結(jié)構(gòu)體
    //……
    struct mm_struct *mm;//描述進(jìn)程的整個用戶空間
    }
    而stuct mm_struct 結(jié)構(gòu)中包含了虛擬空間的結(jié)構(gòu)體字段
    mmap(struct vm_area_struct * mmap),所以可以通過模塊編程來查看進(jìn)程的虛擬地址空間。
    關(guān)于模塊編程可以看這里:
    http://www.kerneltravel.net/?p=80,程序清單如下:


     #include <linux/module.h>                                                                                     
     #include 
    <linux/init.h>
     #include 
    <linux/interrupt.h>
     #include 
    <linux/sched.h>
     
    static int pid;
     module_param(pid,
    int,0644);
     
    static int __init memtest_init(void)
     {
             
    struct task_struct *p;
             
    struct vm_area_struct *temp;
             printk(
    "My module worked!\n");
             p 
    = find_task_by_vpid(pid);
             temp 
    = p->mm->mmap;
             
    while(temp) {
                     printk(
    "start:%p\tend:%p\n", (unsigned long *)temp->vm_start,
     (unsigned 
    long *)temp->vm_end);
                     temp 
    = temp->vm_next;
             }  
             
    return 0;
     }
     
    static void __exit memtest_exit(void)
     {
             printk(
    "Unloading my module.\n");
             
    return;
     }
     module_init(memtest_init);
     module_exit(memtest_exit);
     MODULE_LICENSE(
    "GPL");  

    編譯模塊,運行剛才的程序test_wait,然后帶參數(shù)插入模塊,如下:
    $ ./test_wait &
    pid is :9413
    $ sudo insmod mem.ko pid=9413
    [ 2690.715913] My module worked!
    [ 2690.715992] start:08048000    end:08049000
    [ 2690.716005] start:08049000    end:0804a000
    [ 2690.717029] start:0804a000    end:0804b000
    [ 2690.717065] start:096d5000    end:096f6000
    [ 2690.717096] start:b7dee000    end:b7def000
    [ 2690.717126] start:b7def000     end:b7f47000
    [ 2690.717157] start:b7f47000     end:b7f49000
    [ 2690.717187] start:b7f49000     end:b7f4a000
    [ 2690.717217] start:b7f4a000     end:b7f4d000
    [ 2690.717248] start:b7f59000     end:b7f5c000
    [ 2690.717304] start:b7f5c000     end:b7f76000
    [ 2690.717334] start:b7f76000     end:b7f77000
    [ 2690.717364] start:b7f77000     end:b7f78000
    [ 2690.717395] start:b7f78000     end:b7f79000
    [ 2690.717425] start:bf964000     end:bf979000
    可以看出和剛才/proc文件系統(tǒng)中的地址是一樣的。
    在任意一個時刻,一個CPU只有一個進(jìn)程在運行,所以雖然有時候很多進(jìn)程的虛擬地址值有相同的
    ,但是由于每次只有一個進(jìn)程運行,在當(dāng)某個進(jìn)程運行時cpu就將其虛擬地址也切換進(jìn)來,這樣就保
    證了每個進(jìn)程都擁有4GB的地址空間。

    posted on 2009-11-16 13:15 BlakeSu 閱讀(434) 評論(2)  編輯  收藏

    評論

    # re: 進(jìn)程的地址空間[未登錄] 2009-11-17 09:07 Frank

    牛,內(nèi)核呀!發(fā)了幾次都不成功,郁悶!  回復(fù)  更多評論   

    # re: 進(jìn)程的地址空間 2009-11-17 10:54

    很核心啊,好好學(xué)習(xí),天天向上  回復(fù)  更多評論   


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲一卡2卡3卡4卡国产网站| 亚洲成年看片在线观看| 亚洲精品高清国产一线久久| 精品久久亚洲一级α| 国产精品免费_区二区三区观看| 久久精品亚洲AV久久久无码| 黄色片在线免费观看| 亚洲黄色免费网址| 无码国产精品一区二区免费虚拟VR| 亚洲欧洲中文日产| 在人线av无码免费高潮喷水| 亚洲大香伊人蕉在人依线| 无码中文在线二区免费| 亚洲sm另类一区二区三区| 免费一看一级毛片| 国产免费伦精品一区二区三区| 亚洲精品无码久久久久sm| 久久久久国产精品免费免费不卡| 亚洲精品午夜视频| 免费国产作爱视频网站| 国产成人 亚洲欧洲| 亚洲午夜久久久久久久久久| 久久一区二区免费播放| 亚洲精品第五页中文字幕| 成人毛片免费播放| eeuss在线兵区免费观看| 亚洲av日韩av不卡在线观看| 国产日本一线在线观看免费| 国产亚洲综合久久| 亚洲AV无一区二区三区久久| 久草视频在线免费| 看一级毛片免费观看视频| 久久精品国产亚洲AV麻豆不卡 | 亚洲va久久久久| 亚洲av麻豆aⅴ无码电影| 4444www免费看| 综合偷自拍亚洲乱中文字幕| 亚洲va久久久噜噜噜久久狠狠| 青青青国产在线观看免费网站| 日亚毛片免费乱码不卡一区| 亚洲电影在线播放|