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

IA-32e模式下无法读写4GB以上内存地址的问题求助

问题根源与修复方案

核心问题:页表覆盖范围不足

你的页表仅配置了PDPT索引0的项,只能映射0-1GB的虚拟地址。4GB以上的地址(如0x100000000)属于PDPT索引4的范围(每个PDPT项对应1GB),但你未为该索引配置页表项,导致访问时触发缺页异常,最终表现为读写无效果。同时,页表项标志位不完整也加剧了错误。


具体修复步骤

1. 扩展PDPT表,添加4GB对应索引的项

修改PAGE_DIRECTROIC_POINTER_TABLE0,补充索引4的项,指向新的PD表物理地址(需4KB对齐):

PAGE_DIRECTROIC_POINTER_TABLE0:
    dq 0000000000003003h  ; 原索引0,指向0x3000的PD表,添加可写位(RW,第1位)
    times 4 dq 0           ; 填充索引1-3的空项
    dq 0000000000005003h  ; 索引4,指向0x5000的PD表,用于映射4GB-5GB
PAGE_DIRECTROIC_POINTER_TABLE_END:

2. 创建新的PD表,用于映射4GB区域

新增PD表,指向对应PT表:

PAGE_DIRECTROIC_TABLE1:  ; 4GB-5GB对应的PD表
    dq 0000000000006003h  ; 指向0x6000的PT表,标志位含存在位(P)+可写位(RW)
PAGE_DIRECTROIC_TABLE1_END:

3. 创建对应PT表,映射4GB起始的4KB页

新增PT表项,将4GB起始虚拟地址映射到目标物理地址(需4KB对齐):

PAGE_L3_4GB:
    dq 0000000a00000003h  ; 虚拟地址0x100000000 → 物理地址0xA00000000,含P+RW位
PAGE_L3_4GB_END:

4. 复制新增页表到物理内存

在16位初始化部分,添加复制新PD表和PT表的代码:

; 复制4GB区域的PD表
mov ax,0
mov ds,ax
mov es,ax
mov si,PAGE_DIRECTROIC_TABLE1
mov di,00005000h
mov cx,PAGE_DIRECTROIC_TABLE1_END - PAGE_DIRECTROIC_TABLE1
cld     
rep movsb                          

; 复制4GB对应的PT表
mov ax,0
mov ds,ax
mov es,ax
mov si,PAGE_L3_4GB
mov di,00006000h
mov cx,PAGE_L3_4GB_END - PAGE_L3_4GB
cld     
rep movsb

5. 修改测试代码,访问正确的4GB虚拟地址

调整test4gb块,访问4GB起始的虚拟地址:

test4gb:
    mov al,'w'
    mov byte [0x100000000],al  ; 访问4GB以上的虚拟地址
    mov bl,byte [0x100000000]
    mov byte [0x20],bl          ; 将读取的值显示到屏幕

    jmp $

额外注意事项

  • 页表对齐:所有页表(PML4、PDPT、PD、PT)必须在4KB(0x1000)地址边界对齐,你的代码已满足此要求。
  • 标志位设置:页表项低12位为控制标志,至少需设置P(存在位,第0位)和RW(可写位,第1位),否则无法正常读写。若需用户态访问,还需设置US位(第2位)。
  • 物理地址有效性:确保映射的物理地址实际存在,建议先用虚拟机(如QEMU)测试,避免硬件限制导致的问题。

内容的提问来源于stack exchange,提问作者sanzenyou

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 18:37:02