C++ 中的虚拟地址到物理地址转换与 & 0xfff 位运算详解

在计算机系统中,为了提高内存利用率和安全性,通常采用虚拟内存技术。虚拟内存将物理内存抽象成一个连续的地址空间,每个进程拥有自己的虚拟地址空间,而实际的物理地址则由操作系统进行管理和映射。

在 C++ 代码中,我们经常需要进行虚拟地址和物理地址之间的转换。其中,& 0xfff 位运算符常用于提取虚拟地址中的偏移量,以便进行地址转换。

代码示例

#include <iostream>

using namespace std;

struct PageTableEntry {
    unsigned char pageFramNr;
    bool pa;
};

struct PageTable {
    PageTableEntry pte[256];
} pageTable;

int main() {
    unsigned short virtualAddr;
    // 输入虚拟地址
    cin >> virtualAddr;
    if (virtualAddr > 65535) virtualAddr = 65535;

    // 取出地址的前四位
    unsigned char p = (virtualAddr >> 12);
    unsigned short offset = virtualAddr & 0xfff;

    if (!pageTable.pte[p].pa) {
        cout << 'Page fault!' << endl;
        return 0;
    }
    unsigned char pageFrame = pageTable.pte[p].pageFramNr;
    unsigned short physicalAddr = (pageFrame << 12) | offset;
    cout << physicalAddr << endl;

    return 0;
}

& 0xfff 位运算符的作用

在上述代码中,& 0xfff 用于提取虚拟地址 virtualAddr 的低 12 位,即偏移量 offset

  • 0xfff 是一个十六进制数,转换为十进制为 4095,二进制表示为 1111 1111 1111
  • 按位与运算 & 会将两个操作数的每一位进行比较,如果两个操作数的对应位都为 1,则结果的该位为 1,否则为 0。

因此,virtualAddr & 0xfff 的作用就是将 virtualAddr 高于 12 位的值全部清零,只保留低 12 位的值,从而得到页面内的偏移量。

虚拟地址到物理地址的转换过程

  1. 提取虚拟地址的高位,即页面号 p,用于在页表中查找对应的页面表项。
  2. 提取虚拟地址的低位,即偏移量 offset
  3. 根据页面号 p 在页表中查找对应的物理页帧号 pageFrame
  4. 将物理页帧号 pageFrame 左移 12 位,并将偏移量 offset 与其进行按位或运算,得到最终的物理地址 physicalAddr

总结

& 0xfff 位运算符在虚拟地址到物理地址的转换过程中起着至关重要的作用,它能够帮助我们快速地提取虚拟地址中的偏移量,从而完成地址转换操作。理解虚拟内存和地址转换的原理,对于 C++ 程序员来说至关重要,它可以帮助我们更好地理解程序的运行机制,编写出更加高效和安全的代码。

C++ 中的虚拟地址到物理地址转换与 & 0xfff 位运算详解

原文地址: https://www.cveoy.top/t/topic/M6e 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录