如何使用页表将虚拟地址转换为物理地址?

时间:2009-05-06 20:08:59

标签: memory memory-management paging virtual-memory memory-address

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

页面表(页面大小= 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”的物理地址?

5 个答案:

答案 0 :(得分: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(由于内存为0索引,因此需要“-1”。)

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

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

23999 + 2844 = 26843 = 0x68DB

24575 + 2844 = 27419 = 0x6B1B

完成!

希望这(编辑)有用XD

编辑: 感谢Jel抓住我的错误:) 感谢user8抓住我的其他错误! (frameNum而不是pageNum)。

答案 1 :(得分:1)

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

顺便说一下,你可能会发现更多的人会在面向操作系统的网站上理解这类问题,例如OSDev。我不能在这个答案中详细说明,因为我多年来没有做过这种类型的事情。

答案 2 :(得分: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();
        }

    }

答案 3 :(得分:1)

第一步:51996/4000 = 12 - &gt; p,保持= 3996 - &gt; d(偏移)。

现在查看表p(12)= 6

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

物理地址是27996.

答案 4 :(得分: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 II。 0x00ED III。 0xEA14 IV。 0x6901 v.0x23A1 六。 0xA999