亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 3186 | 回復(fù): 9
打印 上一主題 下一主題

[內(nèi)存管理] 虛擬地址 邏輯地址 線性地址 物理地址 虛擬存儲器 物理存儲器 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2014-06-20 15:42 |只看該作者 |倒序瀏覽
有關(guān)于上述幾類的地址,最近有做學(xué)習(xí)和整理,基本上是明白其含義,但是還不夠火候

在此一來作為學(xué)習(xí)的標記,二來還希望大家可以不吝賜教

下面篇幅有點長,內(nèi)容有點雜亂,問題也有點小多;望各位耐心看完 :wink:

相關(guān)帖子,有看過一些。比如: http://72891.cn/forum.php?mod=viewthread&tid=2083672

理解上

由于intel(32位)處理器的分段機制,因此有了 邏輯地址的概念,其組成是 段選擇符(16位) + 段內(nèi)偏移量(32位)。該邏輯地址由cpu的分段單元解析后,得到32位線性地址。

如果沒有分頁部件的存在,該線性地址就對應(yīng)于物理地址

分頁部件把該線性地址轉(zhuǎn)化成物理地址。根據(jù)查找頁表來進行轉(zhuǎn)化



在微機原理書上有說明,對于32位微處理器,可以訪問2^32字節(jié)的物理存儲器,但它支持多任務(wù)時,每個任務(wù)又能得到最大為2^46字節(jié)

物理存儲器對應(yīng)于物理上的內(nèi)存,是cpu可以訪問的存儲器空間
虛擬存儲器是程序占有的空間,其容量由cpu的內(nèi)部結(jié)構(gòu)所決定

對于8086cpu來說,程序占有的虛擬存儲器和cpu能訪問的存儲器是一致的,都是1M。(8086的地址總線是20位)
對于 32位的cpu來說,兩者是不同的。cpu最大可以訪問的存儲器是 4G, 而對于存儲在磁盤的程序而言,最大可以寫 2^46字節(jié)的程序

對于以上的理解,有
問題一: 為何在支持多任務(wù)時候,每個任務(wù)會有2^46字節(jié)。同時邏輯地址到底是48位還是46位?

看起來說和 cpu的內(nèi)部結(jié)構(gòu)有關(guān)。對于這個 46字節(jié),根據(jù)后續(xù)的介紹有: 14位的段選擇符 + 32位的段內(nèi)偏移
因為段選擇符的最低兩位是相關(guān)的權(quán)限標志位。不知以上理解是否正確

以上都是有關(guān)理論上的知識,有
問題二:對于邏輯地址,在哪可以比較直白的看到該地址的存在?或者說通過什么方式我們可以看到這 48/46位的邏輯地址

我們可以通過使用 readelf -S a.out(參考下面的問題三中的討論)可以來查看程序的虛擬內(nèi)存空間。理論上我們在此可以看到最大 2^46大小的虛擬內(nèi)存空間。

我理解上,其中列出的就是虛擬地址,也就等同于上述所說的 邏輯地址的偏移量。

對于上述的邏輯地址,后來在翻書時候有注意到,對于匯編語言中的直接尋址方式。(以下是8086cpu,也就是20位地址總線,16位數(shù)據(jù)總線結(jié)構(gòu)的)

比如 “ mov AX, [1070H]“ 該操作是將 DS段的 1070H和 1071H兩單元的內(nèi)容放置到 AX中。因為直接尋址的默認段寄存器是 DS

如果要指定其他段寄存器,應(yīng)該指令前用前綴指定段寄存器名稱,比如 ” CS:mov BX, [3000H]“

以上兩個指令,假設(shè) DS為2000H, CS為5100H
指令一就是將 21070H和 21071H兩單元內(nèi)容存放到 AX中(DS向左偏移4位后加上后續(xù)的偏移量組成)
指令二是將 54000H和 54001H兩單元內(nèi)容存放到 BX中

21070H是邏輯地址還是線性地址??
如果是邏輯地址,是否說在匯編語言中可以查看到 邏輯地址的蹤跡?


對于 程序,參考某網(wǎng)絡(luò)上相關(guān)程序內(nèi)存布局的文章
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. int global_init_a=1;
  4. int global_uninit_a;

  5. int main()
  6. {
  7.     int local_init_a=1;
  8.     int local_uninit_a;

  9.     int * malloc_p_a;
  10.     malloc_p_a=malloc(sizeof(int));

  11.     printf("\n         &global_init_a=%p \t          "
  12.          "global_init_a=%d\n",&global_init_a,global_init_a);

  13.     printf("       &global_uninit_a=%p \t       "
  14.         "global_uninit_a=%d\n",&global_uninit_a,global_uninit_a);   


  15.     printf("\n          &local_init_a=%p \t          "
  16.         "local_init_a=%d\n",&local_init_a,local_init_a);

  17.     printf("        &local_uninit_a=%p \t        "
  18.         "local_uninit_a=%d\n",&local_uninit_a,local_uninit_a);
  19.    
  20.     printf("             malloc_p_a=%p \t           "
  21.         "*malloc_p_a=%d\n",malloc_p_a,*malloc_p_a);
  22.    
  23.     while(1);
  24.     return 0;
  25. }
復(fù)制代碼
運行結(jié)果:
  1. [martin@stack]$ gcc process_mem.c
  2. [martin@stack]$ ./a.out &
  3. [1] 7418
  4. [martin@stack]$
  5.          &global_init_a=0x804a024                   global_init_a=1
  6.        &global_uninit_a=0x804a02c                global_uninit_a=0

  7.           &local_init_a=0xbfb1f5a4                   local_init_a=1
  8.         &local_uninit_a=0xbfb1f5a8                 local_uninit_a=134513931
  9.              malloc_p_a=0x8758008                    *malloc_p_a=0

  10. [martin@stack]$
復(fù)制代碼
查看進程的maps
  1. [martin@stack]$ sudo cat /proc/7418/maps
  2. 08048000-08049000 r-xp 00000000 08:08 1700899    /home/martin/debug/work/test/stack/a.out
  3. 08049000-0804a000 r--p 00000000 08:08 1700899    /home/martin/debug/work/test/stack/a.out
  4. 0804a000-0804b000 rw-p 00001000 08:08 1700899    /home/martin/debug/work/test/stack/a.out
  5. 08758000-08779000 rw-p 00000000 00:00 0          [heap]
  6. b7542000-b7543000 rw-p 00000000 00:00 0
  7. b7543000-b76ec000 r-xp 00000000 08:0a 1570780    /lib/i386-linux-gnu/libc-2.19.so
  8. b76ec000-b76ee000 r--p 001a9000 08:0a 1570780    /lib/i386-linux-gnu/libc-2.19.so
  9. b76ee000-b76ef000 rw-p 001ab000 08:0a 1570780    /lib/i386-linux-gnu/libc-2.19.so
  10. b76ef000-b76f2000 rw-p 00000000 00:00 0
  11. b7709000-b770c000 rw-p 00000000 00:00 0
  12. b770c000-b770d000 r-xp 00000000 00:00 0          [vdso]
  13. b770d000-b772d000 r-xp 00000000 08:0a 1570756    /lib/i386-linux-gnu/ld-2.19.so
  14. b772d000-b772e000 r--p 0001f000 08:0a 1570756    /lib/i386-linux-gnu/ld-2.19.so
  15. b772e000-b772f000 rw-p 00020000 08:0a 1570756    /lib/i386-linux-gnu/ld-2.19.so
  16. bfb00000-bfb21000 rw-p 00000000 00:00 0          [stack]
  17. [martin@stack]$
復(fù)制代碼
使用 readelf查看 a.out程序的Stack
  1. [martin@stack]$ readelf -S a.out
  2. There are 30 section headers, starting at offset 0x1154:

  3. Section Headers:
  4.   [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  5.   [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  6.   [ 1] .interp           PROGBITS        08048154 000154 000013 00   A  0   0  1
  7.   [ 2] .note.ABI-tag     NOTE            08048168 000168 000020 00   A  0   0  4
  8.   [ 3] .note.gnu.build-i NOTE            08048188 000188 000024 00   A  0   0  4
  9.   [ 4] .gnu.hash         GNU_HASH        080481ac 0001ac 000020 04   A  5   0  4
  10.   [ 5] .dynsym           DYNSYM          080481cc 0001cc 000060 10   A  6   1  4
  11.   [ 6] .dynstr           STRTAB          0804822c 00022c 000053 00   A  0   0  1
  12.   [ 7] .gnu.version      VERSYM          08048280 000280 00000c 02   A  5   0  2
  13.   [ 8] .gnu.version_r    VERNEED         0804828c 00028c 000020 00   A  6   1  4
  14.   [ 9] .rel.dyn          REL             080482ac 0002ac 000008 08   A  5   0  4
  15.   [10] .rel.plt          REL             080482b4 0002b4 000020 08   A  5  12  4
  16.   [11] .init             PROGBITS        080482d4 0002d4 000023 00  AX  0   0  4
  17.   [12] .plt              PROGBITS        08048300 000300 000050 04  AX  0   0 16
  18.   [13] .text             PROGBITS        08048350 000350 000222 00  AX  0   0 16
  19.   [14] .fini             PROGBITS        08048574 000574 000014 00  AX  0   0  4
  20.   [15] .rodata           PROGBITS        08048588 000588 000123 00   A  0   0  4
  21.   [16] .eh_frame_hdr     PROGBITS        080486ac 0006ac 00002c 00   A  0   0  4
  22.   [17] .eh_frame         PROGBITS        080486d8 0006d8 0000ac 00   A  0   0  4
  23.   [18] .init_array       INIT_ARRAY      08049f08 000f08 000004 00  WA  0   0  4
  24.   [19] .fini_array       FINI_ARRAY      08049f0c 000f0c 000004 00  WA  0   0  4
  25.   [20] .jcr              PROGBITS        08049f10 000f10 000004 00  WA  0   0  4
  26.   [21] .dynamic          DYNAMIC         08049f14 000f14 0000e8 08  WA  6   0  4
  27.   [22] .got              PROGBITS        08049ffc 000ffc 000004 04  WA  0   0  4
  28.   [23] .got.plt          PROGBITS        0804a000 001000 00001c 04  WA  0   0  4
  29.   [24] .data             PROGBITS        0804a01c 00101c 00000c 00  WA  0   0  4
  30.   [25] .bss              NOBITS          0804a028 001028 000008 00  WA  0   0  4
  31.   [26] .comment          PROGBITS        00000000 001028 000024 01  MS  0   0  1
  32.   [27] .shstrtab         STRTAB          00000000 00104c 000106 00      0   0  1
  33.   [28] .symtab           SYMTAB          00000000 001604 000460 10     29  45  4
  34.   [29] .strtab           STRTAB          00000000 001a64 000288 00      0   0  1
  35. Key to Flags:
  36.   W (write), A (alloc), X (execute), M (merge), S (strings)
  37.   I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  38.   O (extra OS processing required) o (OS specific), p (processor specific)
  39. [martin@stack]$
復(fù)制代碼
重點在于進程的 maps表,從 readelf可以看出,程序的 bss和 data數(shù)據(jù)段的虛擬地址是  0804a01c,這個應(yīng)該是程序的虛擬內(nèi)存空間。根據(jù)以上討論,該虛擬內(nèi)存空間可以大于 4G
該地址也可以在進程的maps中看到。

問題三:對于進程的 maps中,stack的地址 bfb00000應(yīng)該是該進程占用的實際物理內(nèi)存空間的物理地址,那為何還會有類似 08049000地址,這個不是程序的虛擬地址么?
這個有可能是針對 linux進程的內(nèi)存管理方面的知識,不是特別清楚,所以也在此咨詢下各位大嬸

論壇徽章:
0
2 [報告]
發(fā)表于 2014-06-20 16:08 |只看該作者
ULK中在分段一節(jié)有說到:x86中的分段鼓勵程序員將程序劃分成邏輯上相關(guān)的實體,例如子程序或者全局與局部數(shù)據(jù)區(qū)

是否是指代常說的 代碼段,數(shù)據(jù)段,堆棧段等一段段的實體?

同時代碼段是否也有必要分成不同的邏輯段??

論壇徽章:
7
2015年亞洲杯之約旦
日期:2015-03-05 17:03:522015亞冠之山東魯能
日期:2015-09-29 13:01:2115-16賽季CBA聯(lián)賽之四川
日期:2016-01-18 15:47:0215-16賽季CBA聯(lián)賽之廣夏
日期:2016-02-24 11:47:1515-16賽季CBA聯(lián)賽之遼寧
日期:2016-11-01 09:45:4115-16賽季CBA聯(lián)賽之青島
日期:2017-02-15 10:02:182016科比退役紀念章
日期:2017-02-16 17:25:35
3 [報告]
發(fā)表于 2014-06-20 17:14 |只看該作者
看內(nèi)核有用處不?
我看了一年內(nèi)核,可出來找工作卻找不到做內(nèi)核的

論壇徽章:
0
4 [報告]
發(fā)表于 2014-06-20 17:20 |只看該作者
回復(fù) 3# linggang_123


    這個真不好說。
之前l(fā)inux的項目倒是會設(shè)計內(nèi)核的一些修改
現(xiàn)在在 ecos下面,基本上不太會涉及 linux的東西

現(xiàn)在再看linux的kernel,主要也就是:
1. 真心想了解其kernel的內(nèi)容,增加知識積累了
2. 為以后可能的用途做準備,書到用時方恨少么。了解了,有些也就通了

論壇徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辭舊歲徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亞洲杯之卡塔爾
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08處女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技術(shù)圖書徽章
日期:2014-03-25 09:00:29
5 [報告]
發(fā)表于 2014-06-23 08:52 |只看該作者
Linux內(nèi)核沒有使用實際分段機制,所以,邏輯地址相當于沒用~
“對于進程的 maps中,stack的地址 bfb00000應(yīng)該是該進程占用的實際物理內(nèi)存空間的物理地址”----這個應(yīng)該是虛擬地址。

論壇徽章:
0
6 [報告]
發(fā)表于 2014-06-23 18:06 |只看該作者
回復(fù) 5# humjb_1983


    查看代碼來看,確實是打印程序的線性地址空間
  1. static int nommu_vma_list_show(struct seq_file *m, void *v)
  2. {
  3.     struct vm_area_struct *vma;
  4. ...
  5.     seq_printf(m,
  6.            "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
  7.            vma->vm_start,                                                                                                                             
  8.            vma->vm_end,
  9.            flags & VM_READ ? 'r' : '-',
  10.            flags & VM_WRITE ? 'w' : '-',
  11.            flags & VM_EXEC ? 'x' : '-',
  12.            flags & VM_MAYSHARE ? flags & VM_SHARED ? 'S' : 's' : 'p',
  13.            vma->vm_pgoff << PAGE_SHIFT,
  14.            MAJOR(dev), MINOR(dev), ino, &len);
  15. ...
  16. }
復(fù)制代碼

論壇徽章:
0
7 [報告]
發(fā)表于 2014-06-23 18:22 |只看該作者
對于
問題二:對于邏輯地址,在哪可以比較直白的看到該地址的存在?或者說通過什么方式我們可以看到這 48/46位的邏輯地址

mov AX, [1070H]
其中 邏輯地址是 DS:偏移量 1070
通過加法器得到的 21070是線性地址,也是物理地址

因此,邏輯地址是可以在匯編中看得到的

比如對于代碼段的尋址,其邏輯地址應(yīng)該是 CS:IP,其中IP會作為其偏移量存在,
同樣對于堆棧段,邏輯地址就是 SS:ESP,其中 ESP是偏移量

論壇徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辭舊歲徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亞洲杯之卡塔爾
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08處女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技術(shù)圖書徽章
日期:2014-03-25 09:00:29
8 [報告]
發(fā)表于 2014-06-23 22:07 |只看該作者
abin9630 發(fā)表于 2014-06-23 18:22
對于
問題二:對于邏輯地址,在哪可以比較直白的看到該地址的存在?或者說通過什么方式我們可以看到這 48/ ...

呵呵,這個差不多,但之前說了linux其實沒有用分段機制,CS、DS、內(nèi)核和用戶態(tài)都是0.

論壇徽章:
0
9 [報告]
發(fā)表于 2014-06-23 22:12 |只看該作者
回復(fù) 8# humjb_1983


注意段寄存器中并不是0,因為里面是段選擇符。它們指向的段中基址是0   

論壇徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辭舊歲徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亞洲杯之卡塔爾
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08處女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技術(shù)圖書徽章
日期:2014-03-25 09:00:29
10 [報告]
發(fā)表于 2014-06-23 22:15 |只看該作者
njuzhyf 發(fā)表于 2014-06-23 22:12
回復(fù) 8# humjb_1983

呵呵,我的意思就是段基址是0.。。
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP