求助:虚拟地址转物理地址的原理理解及代码实现问题
虚拟地址转物理地址流程解析与代码补全
核心转换逻辑拆解
结合你的代码和描述,这里模拟的是16位虚拟地址到物理地址的转换,核心规则:
- 高4位 = 页号(Page Number):用于索引页表数组(PageTable共16项,对应2^4=16个虚拟页)
- 低12位 = 页内偏移(Offset):虚拟页与物理帧大小一致(4KB=2^12字节),该偏移在转换时直接保留
具体转换步骤
- 提取页号:将虚拟地址右移12位,再用
0xF掩码保留低4位(避免符号位干扰),得到页表数组的索引。 - 有效性检查:通过页号找到对应的页表项,若
valid位为0,说明该虚拟页未加载到物理内存,触发缺页异常。 - 拼接物理地址:若有效,取出
frame_Num(物理帧号)左移12位(放到物理地址高位),再与虚拟地址的低12位偏移做按位或,得到最终物理地址。
补全后的代码
#include <stdio.h> #include <unistd.h> #include <stdlib.h> struct Map{ unsigned int frame_Num : 3; unsigned int valid : 1; }; struct Map PageTable[16]; void createPageTable(){ PageTable[0].frame_Num = 0x2; PageTable[0].valid = 1; PageTable[1].frame_Num = 0x1; PageTable[1].valid = 1; PageTable[2].frame_Num = 0x6; PageTable[2].valid = 1; PageTable[3].frame_Num = 0x0; PageTable[3].valid = 0; PageTable[4].frame_Num = 0x4; PageTable[4].valid = 1; PageTable[5].frame_Num = 0x3; PageTable[5].valid = 1; PageTable[6].frame_Num = 0x0; PageTable[6].valid = 0; PageTable[7].frame_Num = 0x0; PageTable[7].valid = 0; PageTable[8].frame_Num = 0x0; PageTable[8].valid = 0; PageTable[9].frame_Num = 0x5; PageTable[9].valid = 1; PageTable[10].frame_Num = 0x0; PageTable[10].valid = 0; PageTable[11].frame_Num = 0x7; PageTable[11].valid = 1; PageTable[12].frame_Num = 0x0; PageTable[12].valid = 0; PageTable[13].frame_Num = 0x0; PageTable[13].valid = 0; PageTable[14].frame_Num = 0x0; PageTable[14].valid = 0; PageTable[15].frame_Num = 0x0; PageTable[15].valid = 0; } int translateToPhysicalAddress(int virtualAddress){ // 提取高4位作为页号 int pageNum = (virtualAddress >> 12) & 0xF; // 提取低12位作为页内偏移 int offset = virtualAddress & 0xFFF; // 检查页表项有效性 if (PageTable[pageNum].valid != 1) { printf("虚拟地址0x%x触发缺页异常\n", virtualAddress); return -1; } // 拼接物理地址:帧号左移12位 + 页内偏移 int physicalAddress = (PageTable[pageNum].frame_Num << 12) | offset; printf("虚拟地址0x%x -> 物理地址0x%x\n", virtualAddress, physicalAddress); return physicalAddress; } int main(){ createPageTable(); // 测试用例 translateToPhysicalAddress(0x0000); // 页号0 -> 物理地址0x2000 translateToPhysicalAddress(0x1FFF); // 页号1 -> 物理地址0x1FFF translateToPhysicalAddress(0x3000); // 页号3 -> 缺页异常 translateToPhysicalAddress(0xB123); // 页号11 -> 物理地址0x7123 return 0; }
关键概念再明确
- 页表:虚拟页到物理帧的映射表,每个条目记录帧号与有效性,确保操作系统能找到虚拟地址对应的物理内存位置。
- 页内偏移:因为虚拟页和物理帧的大小完全一致,页内的字节位置在转换时无需修改,直接复用即可。
- 页号索引:高4位对应16个页表项,与你的PageTable数组长度匹配,因此页号可直接作为数组下标使用。
内容的提问来源于stack exchange,提问作者IronGemini
相关产品推荐
相关产品推荐

