Here is the "algorithm" for translating a virtual address, va, into a physical address, pa. if ( PageTable[va.pageNumber].valid ) { pa = PageTable[va.pageNumber].pageFrameNumber + va.offset; } else { raise_memory_interrupt; } Here are the "data structures" used to do paged address translation. +------------------------------+ va | pageNumber | offset | pageNumber has n bits +------------------------------+ +--------------------------------------+ pa | pageFrameNumber | offset | pageFrameNumber has m bits +--------------------------------------+ +-------------------------------------+ PTE | pageFrameNumber |v|r|w|x|p| // valid, read, write, execute, present, etc., bits +-------------------------------------+ The page table is an array of page table entries (PTE). PTE PageTable[2^n]; // the page table is an array of PTE The number of page table entries is 2^n where n is the number of bits in the pageNumber field of a va. The number of page frames in physical memory is 2^m where n is the number of bits in the pageFrameNumber field of a pa. A PTE includes the pageFrameNumber field and several status bits. The specific status bits in a PTE depend on the CPU architecture. At the very least, there needs to be a "valid" bit to denote that the page frame represented by the PTE is backed by a physical page frame (that is, the data in the pageFrameNumber field is valid data). Here is a (32-bit) example of how a virtual address gets broken up into two fields, the "virtual page number" and the "offset". VPN (20 bits) | offset (12 bits) | va 00000000000000000011 | 101010100010 32-bit virtual address | | 20 bits means 2^20 pages | 12 bits means 2^12 bytes in a page Here is what va, pa, and PTE look like for a 32-bit program (4 GB address space) with, say, 256 MB of physical memory (about 20 years ago). Here, the virtual address space is larger than the physical address space. +------------------------------+ va | pageNumber |0000000000| 32 bits +------------------------------+ |---- 20 bits ------|-12 bits -| +---------------------------+ pa |pageFrameNumber |0000000000| 28 bits +---------------------------+ |--- 16 bits ----|-12 bits -| +----------------------+ PTE |pageFrameNumber |V|P|R| 19 bits +----------------------+ |--- 16 bits ----| Here is what va, pa, and PTE look like for a 32-bit program (4 GB address space) with, say, 16 GB of physical memory (about 10 years ago). Here, the virtual address space is smaller than the physical address space. +------------------------------+ va | pageNumber |0000000000| 32 bits +------------------------------+ |---- 20 bits ------|-12 bits -| +----------------------------------+ pa | pageFrameNumber |0000000000| 36 bits +----------------------------------+ |----- 22 bits ---------|-12 bits -| +-----------------------------+ PTE | pageFrameNumber |V|P|R| 25 bits +-----------------------------+ |----- 22 bits ---------| Here is what va, pa, and PTE look like for a 64-bit program with a 48-bit physical address space (today's computers). Here, the virtual address space is much larger than the physical address space. In fact, each page table alone is bigger than all of the physical address space (let alone physical memory). +--------------------------------------+ va | pageNumber |0000000000| 64 bits (page table, 2^56, is too big!) +--------------------------------------+ |------- 56 bits -----------|-12 bits -| +------------------------------+ pa | pageFrameNumber |0000000000| 48 bits +------------------------------+ |---- 36 bits ------|-12 bits -| +-------------------------+ PTE | pageFrameNumber |V|P|R| 39 bits +-------------------------+ |---- 36 bits ------|