13

假设我有一个普通的页表:

页表(页面大小 = 4k)

      Page #:  0  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15          
Page Frame #:  3  x  1  x  0  x  2  x  5  x   7   4   6   x   x   x

如何将任意逻辑地址(如 51996)转换为物理内存地址?


如果我取 log base 2 (4096),我得到 12。我认为这是我应该使用多少位来偏移地址。

我只是不确定。51996 / 4096 = 12.69。那么这是否意味着它以一定的偏移量位于第 12 页上?

那我怎么把它变成“51996”的物理地址呢?

4

5 回答 5

21

要确定给定内存地址的页面,请取前 P 位(N 位)的编号。

P = lg2(numberOfPages)
在你的例子中, P=lg2(16)=4

所以给定内存地址的前 4 位将告诉我们页面。这意味着其余的应该是从该页面开始的偏移量。

您的示例地址 51996 是二进制的 1100101100011100。即 [1100:101100011100]。

1100(十进制的 12)是页码
101100011100(十进制的 2844)是偏移量

现在我们需要找到第 12 页在内存中的位置。
查看您的框架表,第 12 页似乎位于第 6 个框架中。在所有内存都是可分页的(即没有内存映射 IO)的系统中,第 6 页帧将位于(entriesPerPage*frameNum)-1

在这种情况下,4000*6-1 = 23999(需要“-1”,因为内存是 0 索引的。)

在这种情况下,4096 *6-1 = 24575(需要“-1”,因为内存是 0 索引的。)

现在我们要做的就是添加偏移量,我们就有了物理内存地址:

23999 + 2844=26843 = 0x68DB

24575 + 2844 = 27419 = 0x6B1B

完毕!

希望这个(编辑)有帮助 XD

编辑:感谢 Jel 发现我的错误 :) 感谢 user8 发现我的另一个错误!(frameNum 而不是 pageNum)。

于 2009-05-06T21:04:06.507 回答
1

这可能会有所帮助:

    import java.util.Arrays;
    import java.util.Scanner;

    public class Run {

        private static Scanner input = new Scanner(System.in);

        public static void main(String[] args) {

            System.out.println("////////// COMMANDS //////////");
            System.out.println("Snapshot: S(enter)r, S(enter)m, S(enter)x, S(enter)p, S(enter)d, S(enter)c");
            System.out.println("time: t");
            System.out.println("Terminate: T#");
            System.out.println("Kill: K#");
            System.out.println("Start process: A");
            System.out.println("Quit program: quit");
            System.out.println("Deletes device: delete");
            System.out.println ("//////////////////////////////");
            OS myComputer;
            int hdd, cdd, printer, cpu, mem, page;
            hdd = cdd = printer = cpu = 20;
            mem = 1;
            page = 1;
            System.out.println("");
            System.out.println("|||| SYS GEN ||||");
            System.out.println("");
            mem = 0;
            System.out.println("Number of Hard-Drives:");
            while (hdd > 10) {
                String inpt = input.next();
                while (Asset.isInt(inpt) == false)
                    inpt = input.next();
                hdd = Integer.parseInt(inpt);
                if (hdd > 10)
                    System.out.println("Try something smaller (less than 10)");

            }

            System.out.println("Number of CD-Drives: ");
            while (cdd > 10) {
                String inpt = input.next();
                while (Asset.isInt(inpt) == false)
                    inpt = input.next();
                cdd = Integer.parseInt(inpt);
                if (cdd > 10)
                    System.out.println("Try something smaller (less than 10)");
            }

            System.out.println("Number of Printers:");
            while (printer > 10) {
                String inpt = input.next();
                while (Asset.isInt(inpt) == false)
                    inpt = input.next();
                printer = Integer.parseInt(inpt);
                if (printer > 10)
                    System.out.println("Try something smaller (less than 10)");
            }

            System.out.println("Amount of Memory:");
            while (mem <= 0) {
                String inpt = input.next();
                if (Asset.isInt(inpt))
                    mem = Integer.parseInt(inpt);
                if (mem<=0)
                    System.out.println("The memory size must be greater than zero.");
                else
                    break;
            }

            Integer[] factors = Asset.factors(mem);
            System.out.println("Enter a page size: "+Arrays.toString(factors));
            while (true) {
                String inpt = input.next();
                while (Asset.isInt(inpt) == false)
                    inpt = input.next();
                if (Asset.inArray(factors, Integer.parseInt(inpt))) {
                    page = Integer.parseInt(inpt);
                    break;
                } else {
                    System.out.println("Page size must be one of these -> "+Arrays.toString(factors));
                }
            }

            System.out.println("Number of CPUs (max10):");
            while (cpu > 10) {
                String inpt = input.next();
                while (Asset.isInt(inpt) == false)
                    inpt = input.next();
                cpu = Integer.parseInt(inpt);
                if (cpu > 10)
                    System.out.println("Try something smaller (less than 10)");
            }
            myComputer = new OS(cpu, hdd, cdd, printer, mem, page);
            myComputer.Running();
        }

    }
于 2012-05-10T19:36:43.690 回答
1

如果我正确理解了您的问题(我可能没有正确理解),您想知道如何使用页表结构从虚拟地址中找到物理地址。在这种情况下,假装你是处理器。使用地址的最高 10 位在页目录(顶级页表)中查找页表。接下来的 10 位是页表(较低级别的页表)的索引。使用该页表条目中的地址来查找物理页地址。最后十位是进入页面的字节地址。

顺便说一句,您可能会在OSDev等面向操作系统的站点上找到更多了解此类问题的人。我无法在这个答案中真正详细介绍,因为我已经很多年没有做过这类事情了。

于 2009-05-06T20:31:38.470 回答
1

第一步:51996 / 4000 = 12 -> p,剩余 = 3996 -> d(偏移量)。

现在看表 p(12) = 6

第二步:(6*4000)+3996:27996

物理地址为 27996。

于 2015-05-30T10:22:38.450 回答
0

以下页表适用于具有 16 位虚拟和物理地址以及 4,096 字节页面的系统。当页面被引用时,引用位设置为 1。线程定期将参考位的所有值清零。页框的破折号表示该页不在内存中。页面替换算法是本地化的 LRU,所有数字都以十进制提供。

页 页帧参考位 0 9 0 1 1 0 2 14 0 3 10 0 4 - 0 5 13 0 6 8 0 7 15 0 8 0 0 9 - 0 10 5 0 11 4 0 12 - 0 13 3 0 14 - 0 15 2 0 一个。将以下虚拟地址(十六进制)转换为等效的物理地址(提供十六进制和十进制的答案)。还要为页表中的相应条目设置参考位。(3) 一世。0xBC2C 二。0x00ED 三。0xEA14 四。0x6901 诉 0x23A1 六。0xA999

于 2014-03-04T11:39:44.467 回答