V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
amiwrong123
V2EX  ›  程序员

使用页表进行虚拟地址转换为物理地址时,页内偏移为什么要乘以 4?

  •  
  •   amiwrong123 · 2022-12-22 23:48:43 +08:00 · 2027 次点击
    这是一个创建于 703 天前的主题,其中的信息可能已经有所发展或是发生改变。

    从上图可以看出,一个虚拟地址分为 3 部分:

    • 高 10bit ,从一级页表里,确认到一个项
    • 中间 10bit ,从二级页表里,确认到一个项
    • 低 12bit ,作为页内偏移
    • 最终上图得到的物理地址的低 12bit ,也是 0x050 (0x0000_C050)

    实际上,从我之前了解的页表原理,大概也是这样的。

    但是到了这个图,页内偏移居然要乘以 4 ,这我就很不理解了?

    上图的话,有一个背景,就是让 一级页表的最后一个项,指向一级页表自身。因为在启用页表后,要改读写任何位置,包含改变页表的项的内容,都得经过 虚拟地址转换,这样做的话,就可以方便得 去改变一级页表的某个项的内容,不然的话,还得 做个一级页表二级页表的地址全映射。然后上图就是 这个场景中对虚拟地址的第 3 部分 做处理。

    这个巧妙的过程,我看懂了。但是 为什么这里的页内偏移要乘以 4 ?

    PS:内容来自书籍《 x86 从实模式到保护模式》

    15 条回复    2022-12-23 13:47:42 +08:00
    heiher
        1
    heiher  
       2022-12-22 23:55:46 +08:00 via Android
    最后这图并不是访问数据页吧,而是访问某一级页目录项,指针类型宽度是 32 位。
    amiwrong123
        2
    amiwrong123  
    OP
       2022-12-23 00:03:27 +08:00
    @heiher #1
    但好像不是呀,你能看到 括号里写的是 “做页用”。所以最后这图,已经是在 访问数据页了。

    这个巧妙的用法也把我搞得有点晕了。。
    amiwrong123
        3
    amiwrong123  
    OP
       2022-12-23 00:15:36 +08:00
    为了防止内容不完整,我这里给出 这个巧妙过程的 全过程。下面贴图:
    ![]( https://s3.bmp.ovh/imgs/2022/12/23/03712a39c1313798.png)
    WuSiYu
        4
    WuSiYu  
       2022-12-23 00:16:50 +08:00
    一般是因为内存对齐的需要,比如这里地址都是 4 的整数倍,这样地址二进制的末两位都是 0 ,就没必要存了。存的时候没有这两位,而你算地址的时候就需要把存的值乘 4 ( 2^2)
    amiwrong123
        5
    amiwrong123  
    OP
       2022-12-23 00:27:40 +08:00 via Android
    @WuSiYu
    好像理解你意思,但是有点说不通呀。
    首先,谁也没说这个虚拟地址,必须是四字节对齐的吧。
    第二,假设必须虚拟地址四字节对齐。他也没必要让这个虚拟地址的低 12bit 先右移两位吧,然后到了算物理地址的时候,又要把这 12 个 bit 给左移两位回来==
    ssgong
        6
    ssgong  
       2022-12-23 00:35:13 +08:00
    这里的 4 应该是 page table entry size 的 4bytes
    Nerv
        8
    Nerv  
       2022-12-23 01:10:21 +08:00
    需要修改的是页目录表,三次访问都是在这同一个表。对页目录表的修改以双字为单位,自然要乘 4 。
    amiwrong123
        9
    amiwrong123  
    OP
       2022-12-23 09:35:21 +08:00
    @ssgong #6
    @Nerv #8
    意思好像理解了。看起来处理器好像在搞“特殊化”呢
    - 处理页内偏移时,如果是普通的物理页,那么没有变化。
    - 处理页内偏移时,如果是页目录表,那么需要对 页内偏移乘以 4 再相加。

    但是感觉处理器好像没有这种“能力”做这种特殊化吧,处理器它是 怎么知道的呢。。
    amiwrong123
        10
    amiwrong123  
    OP
       2022-12-23 09:36:14 +08:00
    @ihciah #7
    恕我孤陋寡闻,SDM 是什么,什么网址吗

    看完这本书,我也想实现一遍 书里的程序。
    julyclyde
        11
    julyclyde  
       2022-12-23 09:53:03 +08:00
    UEFI 机型是不是刚开机就保护模式了
    好多人都失去研究这个的机会了
    ForestCo
        13
    ForestCo  
       2022-12-23 10:25:50 +08:00
    对于硬件而言,很多地址的映射需要采用对齐的方式,所以对齐的部分可以不用表示在查找表里,实际取出来用的时候直接右移若干位就行了。关于为什么他是 4Byte 对齐,而不是其他的。不用求甚解我觉得,只要知道是个三段式查找表就行了。这部分知识可以参考《计算机体系结构》
    ForestCo
        14
    ForestCo  
       2022-12-23 10:27:09 +08:00
    @ForestCo *左移若干位
    MstMoonshine
        15
    MstMoonshine  
       2022-12-23 13:47:42 +08:00
    很多 32-bit CPU 硬件上只支持 32 位对齐的地址读取 /写入。这些硬件上如果能对非对齐地址访问,一般是产生 exception 后,由 kernel 对齐地访问附近两个 word 以后把合并起来返回,相当于 emulate 了那条指令。

    此外,地址有没有 32 位对齐,跟是否使用了虚拟地址无关。虚拟地址最后若干位(比如 12 位,0x1000 ,4k page )始终是跟物理地址最后若干位相等的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   917 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 21:10 · PVG 05:10 · LAX 13:10 · JFK 16:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.