c - 给定一个虚拟地址,输出给定地址的页码和偏移量
问题描述
我有这个代码,它返回页码和偏移量,给定一个虚拟地址。我需要帮助来理解这段代码是如何工作的。
pageNumber = (entry & PAGE_NUMBER) >> 12;
这条线尤其让我感到困惑。是什么PAGE NUMBER
?为什么有一个 and 运算符?他们为什么要移动 12 个位置的位?
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PAGE_NUMBER 0xFFFFF000
#define OFFSET 0x00000FFF
int
main(int argc, char *argv[])
{
int pageNumber, offset;
unsigned int entry;
entry = (unsigned int)atoi(argv[1]);
if (argc != 2) {
fprintf(stderr,"Please enter: ./assign4_1 followed by the virtual address in decimal\n");
return -1;
}
printf("The address %d contains:\n",entry);
//mask the page number
pageNumber = (entry & PAGE_NUMBER) >> 12;
offset = entry & OFFSET;
printf("page number = %d\n",pageNumber);
printf("offset = %d\n",offset);
return 0;
}
解决方案
在没有虚拟内存的时代,在任何给定时间,只有一个程序可以跨越计算机上的整个主内存/RAM。如果计算机必须运行多个程序,则必须获取该运行程序的全部状态,将其保存到硬盘等辅助存储设备中,然后允许另一个程序运行,或者必须添加额外的硬件。这时候虚拟内存就派上用场了。
分页是一种从程序的角度抽象出内存管理的机制;因此,对于进程来说,它似乎正在使用整个地址空间,而操作系统的 MMU 将主内存划分为称为页面的固定大小的块,为程序创建整个虚拟地址空间并将它们划分也进入页面。只有需要的页面保存在主存储器中,其他页面写入辅助存储器。当程序引用内存中的地址时,它实际上是指来自该虚拟地址空间的地址,该地址通过页表查找转换为内存中的实际地址。这称为虚拟地址转换。
这不仅允许运行多个程序,还允许运行不适合您的物理地址空间的程序。虚拟地址包括:
- 页码:标识地址所指的虚拟地址空间中的哪些页。
- 页面偏移量:页面的低位,表示该位置距该页面有多少个位置。这些位在翻译过程中不会改变;它保持不变。在您的情况下,三个低位数字或 12 个字节用于页面偏移量。
0xFFFFF000
是您的页码的位掩码。如果您AND
使用任何地址对其进行逻辑处理,它将提取页码。同样,0x00000FFF
是您的页面偏移量的位掩码。
`0xABCDEF12 && 0xFFFFF000 = 0xABCDE000`
`0xABCDEF12 && 0x00000FFF = 0x00000F12`
页偏移量已准备就绪,但页码必须右移 12 位才能更正位置。二进制右移 12 位相当于将十六进制数右移 3 位。
推荐阅读
- ios - iOS - 在 imageView 上针对不同屏幕尺寸按钮的自动布局缩放
- r - 使用 RMarkdown 将带有颜色和 unicode 字符的 kableExtra 表渲染为 PDF
- reactjs - 使用 IBM Watson 进行人脸检测
- .htaccess - HTACCESS:仅重定向没有 jquery 字符串的 .php
- php - 带有子表的表数组数据
- javascript - Javascript - 回调和承诺 - 允许 jsmediatags 在执行函数之前收集专辑封面
- javascript - 在 GNOME 中鼠标进入屏幕上特定像素范围时的激活方法
- java - Java:如何从 mouseEvent/keyboardEvent 方法返回值?
- php - 使用 IP 构成 URL 为空白
- node.js - 快速路线在浏览器中无限旋转