You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:虚拟地址转物理地址的原理理解及代码实现问题

虚拟地址转物理地址流程解析与代码补全

核心转换逻辑拆解

结合你的代码和描述,这里模拟的是16位虚拟地址到物理地址的转换,核心规则:

  • 高4位 = 页号(Page Number):用于索引页表数组(PageTable共16项,对应2^4=16个虚拟页)
  • 低12位 = 页内偏移(Offset):虚拟页与物理帧大小一致(4KB=2^12字节),该偏移在转换时直接保留

具体转换步骤

  1. 提取页号:将虚拟地址右移12位,再用0xF掩码保留低4位(避免符号位干扰),得到页表数组的索引。
  2. 有效性检查:通过页号找到对应的页表项,若valid位为0,说明该虚拟页未加载到物理内存,触发缺页异常。
  3. 拼接物理地址:若有效,取出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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 17:26:05