内存分页

  理解linux内存管理,前面预备知识讲到了i386虚实地址方面的东西,也涉及到了一些内存页式管理的知识。这里主要延伸一下,以一个基于X86_64平台的实例来做一个直观的理解。

代码:

//demo.c
#include <stdio.h>
greeting()                                                                      
{                                                                               
    printf("Hello, world!\n");                                              
}                                                                                                                                                               
main()                                                                          
{                                                                               
    greeting();                                                             
}                  

编译及反汇编:

编译:

gcc -o test demo.c

反汇编:

objdump -d test 
--- 部分反汇编log ---

0000000000400530 <greeting>:
  400530:   55                      push   %rbp
  400531:   48 89 e5                mov    %rsp,%rbp
  400534:   bf e0 05 40 00          mov    $0x4005e0,%edi
  400539:   e8 d2 fe ff ff          callq  400410 <puts@plt>
  40053e:   5d                      pop    %rbp
  40053f:   c3                      retq   

0000000000400540 <main>:
  400540:   55                      push   %rbp
  400541:   48 89 e5                mov    %rsp,%rbp
  400544:   b8 00 00 00 00          mov    $0x0,%eax
  400549:   e8 e2 ff ff ff          callq  400530 <greeting>
  40054e:   5d                      pop    %rbp
  40054f:   c3                      retq  

如上可知

400549: e8 e2 ff ff ff          callq  400530 <greeting>

0x0000000000400530为greeting函数指令存放起始位置,也即需要根据该虚拟地址提取出实际的物理页地址及页内偏移信息。首先根据X86_64的分页管理:
  页大小:4kB
  寻址使用位数:48
  分页级别:4
  线性地址分级:9 + 9 + 9 + 9 + 12

则0x0000000000400530,对应的48bit:
000000000 000000000 000000010 000000000 010100110000

每个分页级别页表有2^9=512个表项,可知上示寻找过程:由第63bit为0得知该地址为虚拟地址后,据某全局寄存器得知L0页表基地址,在结合虚址提供的9bit作为偏移找到了对应的第0表项。根据L0页表中找到的表项得知L1页表的基地址,在据偏移找到L1第0表项。同理找到L2第2表项,L3第0表项,不过此时L3表项中存放的就不是任何页表的基地址了,而是实际对齐的物理页的地址,而低12位即0x530便是页偏移。到此,物理地址就找到了,函数的第一条指令就存放在该页偏移位置处,等待cpu的调度执行。

参考资料:
  linux内核情景分析

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Windows操作系统中,内存分页机制是一种虚拟内存管理技术,用于将物理内存与进程的虚拟地址空间进行映射和管理。内存分页机制的核心概念是将进程的虚拟地址空间划分为固定大小的页面(通常为4KB),并将其映射到物理内存上。 Windows使用了两级的页表结构来实现内存分页机制: 1. 页面目录表(Page Directory Table):页面目录表是一个固定大小的数据结构,用于存储指向页面表的指针。每个页面目录表项(Page Directory Entry)对应着一个页面表。页面目录表通常在系统启动时创建,并且对于每个进程都有一个独立的页面目录表。 2. 页面表(Page Table):页面表是一个固定大小的数据结构,用于将虚拟地址映射到物理地址。每个页面表项(Page Table Entry)包含了虚拟地址与物理地址的对应关系。页面表通常在进程创建时动态生成,并且只包含当前进程所需的页面映射。 通过这两级的页表结构,Windows可以实现虚拟地址到物理地址的映射。当进程访问虚拟地址时,操作系统会根据页表将其转换为物理地址,并进行相应的读取或写入操作。如果所需的页面不在物理内存中,则会触发页面错误(Page Fault),操作系统会将页面从磁盘加载到物理内存中,并更新页表的映射关系。 内存分页机制的好处是可以实现虚拟内存的管理和保护。每个进程都有独立的虚拟地址空间,使得进程之间的内存不会相互干扰,同时允许操作系统灵活地分配和回收物理内存。此外,内存分页机制还支持内存权限控制、页面共享和延迟加载等功能,提高了系统的安全性和性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值