前几天和朋友聊天,他说出去面试 ,面试官问他C++可不可以直接操作物理内存。
这个问题乍一听上去好像在问虚拟内存和物理内存相关的知识,但我觉得回答不能也是不对的,或者说并不是在所有的情况下都不能 .
其实不管是C++也好,汇编也罢,到底访问的是虚拟内存还是物理内存其实看的还是底层的CPU架构.
不论是x86还是ARM都存在real mode或者说real adress mode模式(实模式),
早期的很多CPU基本都是处于这个模式(像8086,8088,80188),在real mode下,经过段机制转化而来的linear address(线性地址)就是物理地址,或者可以说在real模式下没有虚拟地址的概念,各个segment寄存器所装载的段基址都是物理地址。在这种CPU模式下你不论运行什么语言操作的都是物理内存。
当然后来x86架构出现了新的protected mode(保护模式)(x64还有个long mode,不过算是protected mode的扩展版),保护模式下实现了两种内存管理机制:segmentation(段式管理)和paging(分页管理),我们的主板在刚通电的时候是处在实模式的情况下的(bios -> mbr -> loader -> kernel -> os,这些寻址过程是要求准确物理地址的),跑到后面才会进入到protected mode/long mode,而在real mode->protected mode的过程中段式管理机制segmentation必须建立,分页机制paging却是可选的,当paging关闭时,从段式内存管理中得到的linearaddress(线性地址)还是物理地址,我们此时高级语言访问的还是物理内存(当然进入Long Mode时paging必须开启,paging开启后访问的就是虚拟地址)。
除了实模式和未开启paging的情况下我们可以直接操作物理内存,我们都知道现在虚拟存储和物理内存之间一般都是通过MMU来实现的,而MMU是可以被关闭的(当然通电处于实模式时MMU就是关闭状态),除了关闭MMU之外,有的CPU甚至就没有MMU,例如做嵌入式著名的ARM的STM32(linux专门为这类没有MMU的处理器写过uclinux),再这种情况下我们操作的也不是虚拟内存,而是物理内存。当然一般的x86的linux或者windows,mmu都是打开的。但是我们也不能一棍子打死就说类似C++这种高级语言不能操作物理内存。
我也不知道这个面试官是在第一层呢,还是在第二层,或者干脆就是在大气层钓鱼
不过我感觉如果你真的这么回答 他可能觉得你是个大杠精
参考文献:《x86/x64体系探索及编程》