虚拟地址和物理地址的含义

 

虚拟地址和物理地址的概念
    CPU通过地址来访问内存中的单元,地址有虚拟地址和物理地址之分,如果CPU没有MMU(Memory Management Unit,内存管理单元),或者有MMU但没有启用,CPU核在取指令或访问内存时发出的地址将直接传到CPU芯片的外部地址引脚上,直接被内存芯片(以下称为物理内存,以便与虚拟内存区分)接收,这称为物理地址(Physical Address,以下简称PA),如下图所示。

                                                      

                                                                             物理地址示意图

如果CPU启用了MMU,CPU核发出的地址将被MMU截获,从CPU到MMU的地址称为虚拟地址(Virtual Address,以下简称VA),而MMU将这个地址翻译成另一个地址发到CPU芯片的外部地址引脚上,也就是将虚拟地址映射成物理地址,如下图所示[1]。

                                                     

                                                                       虚拟地址示意图

MMU将虚拟地址映射到物理地址是以页(Page)为单位的,对于32位CPU通常一页为4K。例如,虚拟地址0xb700 1000~0xb700 1fff是一个页,可能被MMU映射到物理地址0x2000~0x2fff,物理内存中的一个物理页面也称为一个页框(Page Frame)。

内核也不能直接访问物理地址.但因为内核的虚拟地址和物理地址之间只是一个差值0xc0000000的区别,所以从物理地址求虚拟地址或从虚拟地址求物理地址很容易,+-这个差就行了

物理地址(physical address)
用于内存芯片级的单元寻址,与处理器和CPU连接的地址总线相对应。
——这个概念应该是这几个概念中最好理解的一个,但是值得一提的是,虽然可以直接把物理地址理解成插在机器上那根内存本身,把内存看成一个从0字节一直到最大空量逐字节的编号的大数组,然后把这个数组叫做物理地址,但是事实上,这只是一个硬件提供给软件的抽像,内存的寻址方式并不是这样。所以,说它是“与地址总线相对应”,是更贴切一些,不过抛开对物理内存寻址方式的考虑,直接把物理地址与物理的内存一一对应,也是可以接受的。也许错误的理解更利于形而上的抽像。

虚拟内存(virtual memory)
这是对整个内存(不要与机器上插那条对上号)的抽像描述。它是相对于物理内存来讲的,可以直接理解成“不直实的”,“假的”内存,例如,一个0x08000000内存地址,它并不对就物理地址上那个大数组中0x08000000 - 1那个地址元素;
之所以是这样,是因为现代操作系统都提供了一种内存管理的抽像,即虚拟内存(virtual memory)。进程使用虚拟内存中的地址,由操作系统协助相关硬件,把它“转换”成真正的物理地址。这个“转换”,是所有问题讨论的关键。
有了这样的抽像,一个程序,就可以使用比真实物理地址大得多的地址空间。(拆东墙,补西墙,银行也是这样子做的),甚至多个进程可以使用相同的地址。不奇怪,因为转换后的物理地址并非相同的。
——可以把连接后的程序反编译看一下,发现连接器已经为程序分配了一个地址,例如,要调用某个函数A,代码不是call A,而是call 0x0811111111 ,也就是说,函数A的地址已经被定下来了。没有这样的“转换”,没有虚拟地址的概念,这样做是根本行不通的。
打住了,这个问题再说下去,就收不住了。

逻辑地址(logical address)
Intel为了兼容,将远古时代的段式内存管理方式保留了下来。逻辑地址指的是机器语言指令中,用来指定一个操作数或者是一条指令的地址。以上例,我们说的连接器为A分配的0x08111111这个地址就是逻辑地址。
——不过不好意思,这样说,好像又违背了Intel中段式管理中,对逻辑地址要求,“一个逻辑地址,是由一个段标识符加上一个指定段内相对地址的偏移量,表示为 [段标识符:段内偏移量],也就是说,上例中那个0x08111111,应该表示为[A的代码段标识符: 0x08111111],这样,才完整一些”

线性地址(linear address)或也叫虚拟地址(virtual address)
跟逻辑地址类似,它也是一个不真实的地址,如果逻辑地址是对应的硬件平台段式管理转换前地址的话,那么线性地址则对应了硬件页式内存的转换前地址。

-------------------------------------------------------------
CPU将一个虚拟内存空间中的地址转换为物理地址,需要进行两步:首先将给定一个逻辑地址(其实是段内偏移量,这个一定要理解!!!),CPU要利用其段式内存管理单元,先将为个逻辑地址转换成一个线程地址,再利用其页式内存管理单元,转换为最终物理地址。

这样做两次转换,的确是非常麻烦而且没有必要的,因为直接可以把线性地址抽像给进程。之所以这样冗余,Intel完全是为了兼容而已。

物理地址就是,机器内主存的地址,包括RAM和ROM
逻辑地址就是,程序运行在内存中,使用的地址。
虚拟地址就是,cpu支持的内存空间远远大于机器主存的大小,这些多出来的空间对于程序来说是可以用的,这个时候的所有地址都称为虚拟地址

物理地址:最小系统下的存储器的实际地址,一般只是由CPU内存控制器(地址线)可以管理的容量为最大地址,而实际上这个容量(由地址产生的)远大于实际存在的容量;实际的存储器容量所需要的地址(内存)控制器管理的容量;它的大小一般由芯片决定

逻辑地址:相对程序员而言使用的地址,或说程序无需知道具体的实际地址管理数,而只要在系统(操作)允许范围内使用就行了(这时使用的是一种算法控制下的地址,实际上它只是借用地址概念产生的程序运行模式),它所要说明的是方便,也就是一个线性的(最好)的程序(指令)排列方式。它的大小一般由操作系统决定
虚拟地址:将具有存储功能的所有存储器(不仅仅是最小系统概念下的),进行“统一”编址,而不考虑存储器之间的差异(快慢等),这时的地址是一个比逻辑地址理会数学化的编号(地址),它的大小等往往由应用程序决定。

### 单片机中物理地址虚拟地址的概念及区别 #### 物理地址 在单片机环境中,物理地址是指硬件实际存在的存储单元位置。每个存储单元有唯一的编号,这个编号即为物理地址。当处理器访问特定的物理地址时,可以直接定位到对应的存储器或外设寄存器。 对于单片机而言,由于资源有限,通常不涉及复杂的分页机制,因此其物理地址空间相对简单明了。例如,在AVR单片机上,所有的RAM、Flash以及I/O端口都被映射到了固定的物理地址范围内[^4]。 #### 虚拟地址 相比之下,虚拟地址是在具有高级操作系统的计算机系统中较为常见的概念。然而,在某些复杂的应用场景下,即使是嵌入式设备也可能引入类似的抽象层——比如多任务处理或多租户环境下的隔离需求。此时,“虚拟地址”的含义可以类比于传统PC架构中的定义: - **逻辑地址**:由程序员指定给变量或其他对象的位置; - 经过分段转换得到**线性地址**(仍属于虚拟范畴),最后经页面表进一步映射至具体的**物理地址**[^1]; 但在典型的单片机应用里,所谓的“虚拟地址”更多指的是不同模式下对同一组物理资源的不同解释方式。例如,在保护模式下工作的MCU可能会允许多个独立的任务共享相同的内存区域而不发生冲突,因为它们看到的是各自专属的一套地址映射[^5]。 #### 主要差异 | 对比项 | 物理地址 | 虚拟地址 | |--| | 定义 | 实际存在于硬件上的唯一标识符 | 应用程序视角下的抽象表示形式 | | 可变性 | 不可更改 | 可能随上下文切换而变化 | | 映射关系 | 一对一 | 多对一(多个虚拟地址可能指向同一个物理地址) | | 使用范围 | 直接用于底层控制指令 | 上层软件开发过程中更常用 | 尽管如此,值得注意的是,并非所有类型的微控制器都支持完整的虚拟内存特性。大多数情况下,特别是在较小型号的产品线上,开发者仍然主要依赖直接操纵物理地址来进行编程工作。 ```c // 示例代码展示如何在一个简单的单片机项目中区分这两种地址类型 #include <avr/io.h> void setup() { // 设置DDRB寄存器以配置PB0引脚为输出模式 DDRB |= (1 << DDB0); // 这里的DDRB是一个已知的固定物理地址 } int main(void){ uint8_t *virtualAddress; // 假定此处有一个函数可以根据当前状态动态计算出某个‘虚拟’地址 virtualAddress = calculateVirtualAddress(); // 将LED连接到PB0并通过间接寻址的方式控制它 PORTB = (*virtualAddress); } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值