write_cr3() read_cr3() 修改 CR3 会 改变页表的基地址,相当于 切换页表(如切换进程的虚拟内存映射)。 读取 CR3 可以 获得当前进程的页目录地址。

解析 write_cr3()read_cr3()

这两个函数是 内联汇编(inline assembly),用于在 x86 体系结构读写 CR3 寄存器

📌 CR3(控制寄存器 3)
  • CR3 寄存器x86 32 位分页机制(Paging)中,存储 页目录的物理地址
  • 修改 CR3改变页表的基地址,相当于 切换页表(如切换进程的虚拟内存映射)。
  • 读取 CR3 可以 获得当前进程的页目录地址

1. write_cr3(uint32_t v)

作用:将 v 写入 CR3,用于 设置新的页目录地址

📌 代码

static inline void write_cr3(uint32_t v) {
    __asm__ __volatile__("mov %[v], %%cr3"::[v]"r"(v));
}

📌 解析

  1. __asm__ __volatile__

    • asm 关键字:表示内联汇编
    • volatile:防止编译器优化(因为 CR3 读写影响 CPU 页表)。
  2. mov %[v], %%cr3

    • v 这个变量的值 移动到 CR3,即:
      mov v, %cr3  // 把 v 赋值给 CR3
      
  3. [v] "r"(v)

    • [v]汇编变量占位符
    • "r"(v) 表示 v 存放在通用寄存器(如 eax)。

📌 例子

uint32_t new_page_directory = 0x00100000; // 假设页目录在 1MB 处
write_cr3(new_page_directory);  // 切换页表

将页目录基地址 0x00100000 加载到 CR3,完成页表切换


2. read_cr3()

作用:读取当前 CR3 寄存器的值,获取当前 页目录表的物理地址

📌 代码

static inline uint32_t read_cr3() {
    uint32_t cr3;
    __asm__ __volatile__("mov %%cr3, %[v]":[v]"=r"(cr3));
    return cr3;
}

📌 解析

  1. mov %%cr3, %[v]

    • CR3 读取值cr3 变量,即:
      mov %cr3, cr3  // 把 CR3 值存到 cr3 变量
      
  2. [v] "=r"(cr3)

    • [v]占位符
    • "=r"(cr3) 表示:
      • =:表示这个变量是 输出变量
      • r:存放在通用寄存器(如 eax)。

📌 例子

uint32_t current_cr3 = read_cr3();
printf("当前 CR3: 0x%X\n", current_cr3);

获取当前 CR3 值,输出当前页表的地址。


3. 作用总结

函数作用
write_cr3(uint32_t v)切换页表(修改 CR3)
read_cr3()读取当前 CR3 值
  • write_cr3():用于 切换进程页表,如 fork()execve()
  • read_cr3():用于 调试,查看当前页表基地址。

4. CR3 的作用

分页机制(Paging)中,CR3 主要存储:

  • 页目录基地址(Page Directory Base Address, PDBA)
  • PCD(Page Cache Disable,页缓存禁止)
  • PWT(Page Write-Through,写入策略)

格式(32 位模式)

| 31                  12 | 11  | 10 | 9 - 0 |
| 页目录物理基地址(PDBA) | PCD | PWT | 保留 |
  • 高 20 位页目录的物理地址(必须是 4KB 对齐)。
  • 低 12 位标志位(如缓存策略)。

5. 什么时候用 write_cr3()

  • 进程切换时(Context Switch)

    • 每个进程有自己的页表(Page Table)。
    • write_cr3() 切换到新的页表
    write_cr3(new_process->page_directory);
    
  • 初始化分页时

    • 启动分页(Paging)时,设置 CR3 指向 内核页目录
    write_cr3(kernel_page_directory);
    

6. 结论

read_cr3() 读取当前 CR3(获取页目录基地址)。
write_cr3() 写入 CR3(切换页表,影响虚拟内存)。
CR3 负责页表切换,是进程虚拟内存管理的核心

🚀 x86 分页系统依赖 CR3 切换页表,write_cr3()read_cr3() 是关键工具! 🎯

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值