虚拟地址 线性地址 物理地址 傻傻分不清楚?

本文深入探讨了计算机系统中地址概念的区分,包括逻辑地址、线性地址与物理地址之间的关系及转换过程,特别关注虚拟地址与线性地址在用户空间中的应用与混淆,以及如何将虚拟地址转换为物理地址。

Virtual address  Linear address  Physic address



               


先说说逻辑地址:

           我们时常会看到一种地址的表述方式——segment:offset,比如0x0:0x7c2d

           这里的地址表述方式是逻辑地址方式,在没有开启分段机制之前,物理地址的寻址通过这种方式。

     

          相关的,segment:offset的组织形式,是virtual address,虚拟地址.真正的物理地址是通过 segment<<4 + offset运算得到的.


线性地址:

分段机制开启之后就是使用的线性地址了

比方说下面截图中,那个mov 0x1001c %eax 中的0x1001c就是使用的偏移地址,数据段CS的偏移量,而<bootmain>旁边的那个00007d0a也是地址,代码段的偏移地址,当前obj文件代码段CS内的偏移地址,“(CS:IP)始终指向下一条指令所处的地址”这句话里的地址就是代码段内的偏移地址,下图中的00007d0a,7d0b,7d0e。。。这些都是代码段的偏移地址,而 0x10000这些地址是当前数据段的偏移地址 ,$0x464c457fz只是个立即数

上述下划线部分是最近update

第二次update:      把握住上面下划线的分析,容易知道这里的偏移地址其可以根据seg:offset解析做线性地址,进而根据分页的机制,解析如果映射到物理地址


             上述这个反汇编看到的截图地址和我们平日写hello world反汇编看到的地址无异,都是使用的线性地址。而由于普通的user space用户一般都不会去接触boot.S那段代码。所以根本就没有逻辑地址的“需求”.对于普通用户来说,就两种地址,要么这个地址是"假的" ,要么这个地址是“真的”,这里理解的假,真,都是由于对是否这个地址真正对应物理内存来说的。由于用户空间的线性地址不是真正对应的物理地址,所以人们就把这种地址叫做虚拟地址


所才会有下图(截取自CSAPP)的现象,明明是线性地址空间,被称作虚拟内存空间.


自然的物理内存地址就不必说了.           



之所以这么强调地址概念的区分.一是之前自己晕了好久,半吊子,似懂非懂.

再者,遇到一个问题,触发我去把这个理清楚

看下面的截图,这段代码出自Xv6(MIT-JOS)的 /kern/pmap.h

第一个函数的功能说明是把“takes a kernel virtual address,returns the corresponding physical address”

这里说的把把虚拟地址转换成物理地址就是把线性地址转换成物理地址,

而且实现方法也论证了这一点, 直接的kva - KERNBASE ,这里KERNBASE是0xF0000000

而这里指的“物理地址”也不是别的IO端口的地址,就是内存地址,内存的首地址被映射到KERNBASE

So ...现在就很清楚了


第二个把物理内存地址转换成线性地址就是直接把physical address加上 KERNBASE即可 : -)



总结:

          人们会容易混淆的原因在于直接把线性地址称作虚拟地址了,这并没有错(听线性地址的人也不多吧),对于大多数程序员来说,都是接触的线性地址,由于这个地址不是实际的物理地址,所以就习惯性的称作虚拟地址了.使用范围内也就是这个“虚拟地址”(比方说写个C hello world,里面反汇编也就看到的是线性地址)。 大多数人不需要接触到真正的物理地址,这里的概念就变成了对比性的了,不是物理地址的就是虚拟的,使用的是线性地址,由于"不需要那么多概念",于是就把虚拟地址和线性地址挂钩了,而且这里早期的分段未开启的时候虚拟地址的概念已经不存在了,这样时候不会有重叠,于是大家都这么用了....



仅此个人学习总结,如有误解望及时指正.



<think> 嗯,用户问的是虚拟地址空间中数组和线性表物理地址连续性的差异问题。这个问题涉及到操作系统内存管理和数据结构两个层面的知识,需要分层次解释清楚。 用户可能正在学习数据结构或操作系统课程,遇到了存储连续性的困惑。从ta引用教材内容来看,ta已经掌握了基本概念(如顺序表和链表的区别),但需要更深入理解虚拟内存层面的实现机制。 核心问题在于:虚拟地址连续是否等于物理地址连续?答案是否定的。线性表(特指顺序表)通过单一连续内存块实现,而数组可能被拆分成多个内存块。 让我从三个层面展开: 1. 虚拟内存机制:操作系统通过页表映射地址,虚拟连续≠物理连续 2. 顺序表实现:必须申请整块连续物理内存,否则无法用O(1)公式计算地址 3. 数组实现:特别是多维数组的动态分配,每行可能是独立内存块 用户引用的资料[2]提到“线性表在物理上存储时通常以数组和链式结构”,这里需要强调:当线性表用数组实现时就是顺序表(物理连续),用链表实现则物理不连续。而数组本身作为数据结构,其存储方式更灵活。 对于虚拟地址空间的表现: - 顺序表:在虚拟和物理空间都连续 - 链式线性表:虚拟空间连续(指针串连),物理空间不连续 - 多维数组:虚拟地址连续(编程视角),但物理页可能分散 特别要注意动态分配的多维数组,如用户资料[1]所示的链表存储,每个节点物理位置独立。而资料[3]提到的顺序表O(1)访问特性,正是依赖物理连续性实现的。 最后需要区分编程语言差异:像C语言静态数组在虚拟和物理层都连续,但Java二维数组物理层可能不连续。这个问题实际反映了抽象(虚拟地址)与实现(物理内存)的差异。 </think> 在虚拟地址空间中,数组物理地址空间不一定连续而线性表(特指顺序表)物理地址空间必须连续的根本原因在于**实现机制**和**存储结构**的差异,具体分析如下: --- ### 一、顺序表物理地址空间必然连续的原因 1. **核心机制依赖** 顺序表通过**连续物理存储**实现 $O(1)$ 随机访问。元素地址计算公式为: $$Loc(a_i) = Loc(a_0) + i \times c$$ 其中 $c$ 为元素占用的字节数。该公式成立的前提是物理地址严格连续[^3]。 2. **虚拟地址映射保障** 操作系统为顺序表分配**单块连续虚拟地址空间**,并通过页表映射到**连续的物理页帧**。例如: ```c int seq_list[100]; // 虚拟地址连续 → 物理页帧连续 ``` - **数据访问流程**: CPU生成虚拟地址 → MMU通过页表查找物理页帧 → 访问连续物理内存[^2]。 --- ### 二、数组物理地址空间可能不连续的原因 #### 1. 多维数组的动态分配机制 - **数组的数组结构**(如C/C++/Java): 每行独立分配内存,导致物理分散: ```java int[][] arr = new int[3][]; arr[0] = new int[2]; // 物理块A arr[1] = new int[3]; // 物理块B(与A可能不连续) ``` - **虚拟地址表现**: 虚拟地址连续(`arr[i][j]`的地址线性计算),但物理页帧通过多级页表映射到非连续区域。 #### 2. 语言特性的异构存储 - **Python列表**:存储元素指针而非实际数据,物理地址分散: ```python a = [1, "text", 3.14] # 整数、字符串、浮点数存储在不同物理区域 ``` - **虚拟地址映射**: 列表的虚拟地址连续(指针数组),但指针指向的物理地址不连续。 #### 3. 稀疏数组的存储优化 - 压缩存储技术(如CSR格式)将非零元素分散存储,物理地址不连续但虚拟地址连续。 --- ### 三、关键差异对比 | **特性** | 顺序表 | 数组(多维/动态) | |------------------|---------------------------|---------------------------| | **物理连续性** | 强制连续(公式依赖)[^3] | 可能非连续 | | **虚拟地址表现** | 连续且线性映射 | 连续(但映射可能多级跳转)| | **访问效率** | $O(1)$ 随机访问 | 可能需多次寻址(如指针链)| | **扩容代价** | 整体搬迁(高成本) | 局部扩展(低成本) | --- ### 四、虚拟地址空间的作用 操作系统通过虚拟地址空间提供**连续地址的抽象**: 1. **顺序表**: 虚拟连续 ↔ 物理连续(单块映射)。 2. **非连续数组**: 虚拟连续 ↔ 物理非连续(通过页表多级映射实现"伪连续")。 > **总结**:顺序表因计算寻址公式的刚性要求必须物理连续;而数组可通过虚拟内存机制将连续的虚拟地址映射到非连续的物理页帧,从而支持灵活存储[^2][^3]。 --- ### 相关问题 1. 虚拟地址连续但物理地址不连续时,CPU缓存命中率会如何变化? 2. 哪些数据结构适合用非连续存储提升内存利用率? 3. 如何验证程序中某个数组的物理存储是否连续? 4. 顺序表的连续存储特性对其并发操作有何影响?
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值