C++ 中的虚拟地址到物理地址转换与 & 0xfff 位运算详解
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 位的值,从而得到页面内的偏移量。
虚拟地址到物理地址的转换过程
- 提取虚拟地址的高位,即页面号
p,用于在页表中查找对应的页面表项。 - 提取虚拟地址的低位,即偏移量
offset。 - 根据页面号
p在页表中查找对应的物理页帧号pageFrame。 - 将物理页帧号
pageFrame左移 12 位,并将偏移量offset与其进行按位或运算,得到最终的物理地址physicalAddr。
总结
& 0xfff 位运算符在虚拟地址到物理地址的转换过程中起着至关重要的作用,它能够帮助我们快速地提取虚拟地址中的偏移量,从而完成地址转换操作。理解虚拟内存和地址转换的原理,对于 C++ 程序员来说至关重要,它可以帮助我们更好地理解程序的运行机制,编写出更加高效和安全的代码。
原文地址: https://www.cveoy.top/t/topic/M6e 著作权归作者所有。请勿转载和采集!