80386是一个32位处理器,具有32位可寻址存储空间。Paging子系统的设计者注意到,一个4K页面设计以一种非常整洁的方式映射到这32位中-10位,10位和12位:
+-----------+------------+------------+ | Dir index | Page index | Byte index | +-----------+------------+------------+ 3 2 2 1 1 0 Bit 1 2 1 2 1 0 number
这意味着字节索引为12位宽,它将索引为4K页。Directory和Page索引是10位,每个索引都映射到1,024个条目的表中-如果这些表项每个都是4字节,则每个表将是4K:也是一个Page!
这就是他们所做的:
每个程序都有自己的目录,即一个包含1,024个页面条目的页面,每个页面条目定义了下一级页面表所在的位置-如果有的话。
如果有的话,该页面表将具有1,024个页面条目,每个页面条目定义了最后一级页面的位置-如果有的话。
如果存在,则该页面可以直接读出其字节。
顶级目录和下一页页面表均由1,024个页面条目组成。这些条目中最重要的部分是所索引内容的地址:页面表或实际页面。请注意,此地址不需要完整的32位-由于所有内容都是Page,因此仅高20位是有效的。因此,Page Entry中的其他12位可以用于其他用途:是否甚至存在下一个级别;关于页面是否已被访问或写入的内部管理;甚至是否应该允许写入!
+--------------+----+------+-----+---+---+ | Page Address | OS | Used | Sup | W | P | +--------------+----+------+-----+---+---+ Page Address = Top 20 bits of Page Table or Page address OS = Available for OS use Used = Whether this page has been accessed or written to Sup = Whether this page is Supervisory - only accessible by the OS W = Whether this page is allowed to be Written P = Whether this page is even Present
请注意,如果该P位为0,则允许条目的其余部分具有操作系统想要放入的任何内容-例如页面内容在硬盘上的位置!
如果每个程序都有其自己的目录,则硬件如何知道从何处开始映射?由于CPU一次仅运行一个程序,因此它只有一个控制寄存器来保存当前程序目录的地址。这是页面目录基本寄存器(CR3)。当操作系统在不同程序之间交换时,它将使用程序PDBR的相关页面目录进行更新。
CPU每次访问内存时,都必须将指示的虚拟地址映射到适当的物理地址。这是一个三步过程:
将地址的高10位索引到所指示的页中,PDBR以获取适当的页表的地址;
将地址的后10位索引到目录指示的页面中,以获取适当页面的地址;
索引地址的最后12位以从该页中获取数据。
由于上述步骤1.和2.都使用Page Entries,因此每个Entry都可能表明存在问题:
下一级可以标记为“不存在”;
下一级可以标记为“只读”-操作是写操作;
下一个级别可能被标记为“ Supervisor”-它是访问内存的程序,而不是OS。
当硬件指出了此类问题时,它没有完成访问,而是引发了错误:中断#14,页面错误。它还用故障发生原因的信息填充某些特定的控制寄存器。是否是主管访问权限;以及是否为写入尝试。
期望操作系统捕获该故障,解码控制寄存器,然后决定要做什么。如果访问无效,则可以终止故障程序。如果是虚拟内存访问,则操作系统应分配一个新页面(可能需要腾出已使用的页面!),并用所需的内容(全零或从磁盘加载回的先前内容)填充它),将新页面映射到适当的页面表中,将其标记为存在,然后继续执行错误指示。这次访问将成功进行,并且程序将在不知道发生任何特殊情况的情况下继续运行(除非需要注意时钟!)
主要内容:逻辑地址到物理地址的转换纯粹的分段并不是很流行,并没有被许多操作系统所使用。 但是,分段可以与分页结合使用,以从两种技术中获得最佳功能。 在分段的分页中,主存储器被分成可变大小的段,它们被进一步分成固定大小的页面。 页面比分段小。 每个段都有一个页表,这意味着每个程序都有多个页表。 逻辑地址表示为分段号(基地址),页码和页面偏移量。 分段号 → 它指向相应的分段号。 页码 → 它指向分段中的确切页面。 页面偏移 → 用作
分页: 用户程序的地址空间被划分成若干固定大小的区域,称为“页”,相应地,内存空间分成若干个物理块,页和块的大小相等。可将用户程序的任一页放在内存的任一块中,实现了离散分配。 分段: 将用户程序地址空间分成若干个大小不等的段,每段可以定义一组相对完整的逻辑信息。存储分配时,以段为单位,段与段在内存中可以不相邻接,也实现了离散分配。 分页与分段的主要区别 页是信息的物理单位,分页是为了实现非连续分配
分页与分段比较,如下表所示 - 编号 分页 分段 1 非连续的内存分配 非连续的内存分配 2 分页将程序分成固定大小的分页。 分段将程序分成可变大小的段。 3 由操作系统负责 由编译器负责。 4 分页比分段更快 分段比分页慢 5 分页更接近操作系统 分段更接近用户 6 它会遭受内部碎片问题 它会遭受外部碎片问题 7 没有外部碎片 没有外部碎片 8 逻辑地址分为:页码和页码偏移 逻辑地址分为:分段号
本文向大家介绍thinkphp3.2.3 分页代码分享,包括了thinkphp3.2.3 分页代码分享的使用技巧和注意事项,需要的朋友参考一下 对于thinkphp分页的实现效果,两种调用方法,一种调用公共函数中的函数方法(参考http://www.cnblogs.com/tianguook/p/4326613.html),一种是在模型中书写分页的方法 1、在公共函数Application/C
Django提供了一些类来帮助你管理分页的数据 -- 也就是说,数据被分在不同页面中,并带有“上一页/下一页”标签。这些类位于django/core/paginator.py中。 示例 向Paginator提供对象的列表,以及你想为每一页分配的元素数量,它就会为你提供访问每一页上对象的方法: >>> from django.core.paginator import Paginator >>> o
当一次要在一个页面上显示很多数据时,通常需要将其分成几部分, 每个部分都包含一些数据列表并且一次只显示一部分。这些部分在网页上被称为分页。 Yii 使用 yii\data\Pagination 对象来代表分页方案的有关信息。特别地, total count 指定数据条目的总数。 注意,这个数字通常远远大于需要在一个页面上展示的数据条目。 page size 指定每页包含多少数据条目。 默认值为 2
简介 在 Linux 内核启动过程中的第五部分,我们学到了内核在启动的最早阶段都做了哪些工作。接下来,在我们明白内核如何运行第一个 init 进程之前,内核初始化其他部分,比如加载 initrd ,初始化 lockdep ,以及许多许多其他的工作。 是的,那将有很多不同的事,但是还有更多更多更多关于内存的工作。 在我看来,一般而言,内存管理是 Linux 内核和系统编程最复杂的部分之一。这就是为什
数据库查询时可以直接用 Db 的 paginate 方法 // 查询状态为1的用户数据 并且每页显示10条数据 $users = Db::name('user')->where('user_status',1)->paginate(15); // 把分页数据赋值给模板变量users $this->assign('users', $users); $this->assign('page', $use