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

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

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

    軟件是對質量的不懈追求

    進程的地址空間

    一個程序經過編譯連接后形成的地址空間是一個虛擬地址空間,而Linux在內存尋址時簡化了分段
    機制,使得虛擬地址與線性地址是一致的,比如程序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;
       }
    經過編譯后形成的文件是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,再加上可以通過系統調用進入
    內核的1GB空間,于是每個進程可以擁有4GB的虛擬地址空間(也叫虛擬內存)。某個進程的虛擬地
    址空間可以通過/proc文件系統看到:
    $ ./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]

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

    可以看出代碼段在最低地址依次往上是數據段,空洞、堆棧段在最高地址,棧指針向下移動。
    進程的虛擬地址在保存在內核中的task_struct(PCB)結構中,定義如下:
    struct task_struct { //進程結構體
    //……
    struct mm_struct *mm;//描述進程的整個用戶空間
    }
    而stuct mm_struct 結構中包含了虛擬空間的結構體字段
    mmap(struct vm_area_struct * mmap),所以可以通過模塊編程來查看進程的虛擬地址空間。
    關于模塊編程可以看這里:
    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,然后帶參數插入模塊,如下:
    $ ./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文件系統中的地址是一樣的。
    在任意一個時刻,一個CPU只有一個進程在運行,所以雖然有時候很多進程的虛擬地址值有相同的
    ,但是由于每次只有一個進程運行,在當某個進程運行時cpu就將其虛擬地址也切換進來,這樣就保
    證了每個進程都擁有4GB的地址空間。

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

    評論

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

    牛,內核呀!發了幾次都不成功,郁悶!  回復  更多評論   

    # re: 進程的地址空間 2009-11-17 10:54

    很核心啊,好好學習,天天向上  回復  更多評論   


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


    網站導航:
     
    主站蜘蛛池模板: 77777午夜亚洲| 亚洲人成电影亚洲人成9999网| 亚洲福利电影一区二区?| a视频在线免费观看| 国产午夜亚洲精品午夜鲁丝片| 免费大片黄在线观看| 亚洲av无码成人精品区| 午夜免费国产体验区免费的| 亚洲日本一区二区一本一道 | 伊人免费在线观看高清版| 亚洲国产精品无码久久久久久曰| 精品女同一区二区三区免费播放 | 校园亚洲春色另类小说合集| 搡女人免费视频大全| 亚洲色偷偷综合亚洲av78| 日韩免费在线观看| 国产午夜亚洲精品不卡免下载| 亚洲国产精品无码久久久久久曰| 久久九九久精品国产免费直播| 在线A亚洲老鸭窝天堂| 久久综合九色综合97免费下载 | 亚洲色欲色欲www在线丝| 怡红院免费的全部视频| 亚洲欧洲日韩不卡| 无码国产精品一区二区免费虚拟VR| 亚洲第一区二区快射影院| 国产人妖ts在线观看免费视频| 久久精品成人免费国产片小草| 久久亚洲国产精品五月天| 免费福利视频导航| 精品久久久久亚洲| 亚洲国产精品VA在线看黑人 | 亚洲狠狠婷婷综合久久久久| 亚洲免费在线视频| 亚洲一久久久久久久久| 亚洲国产精品无码久久九九| 亚洲毛片在线免费观看| 羞羞漫画登录页面免费| 伊人久久综在合线亚洲2019| 精品久久免费视频| 美女视频黄a视频全免费网站色窝|