Chris McQueen :
I didn't really know where to post this but I am doing Higher computing, and we have just learned about the equation 2^width of the address bus x the data bus = Maximum amount of addressable memory. My question is, why doesn't it work if I apply this equation to a 32 bit system with a 32-bit address bus width and a 32-bit data bus width. 2^32 x 32 = 13743895350Bytes = 128GB, my understanding was that a 32 bit system can only address 4GB of memory. Thanks in advance.
Your math is a bit off.
2^32 = 4,294,967,296 unique addresses
Most platforms since the System 360 have standardized on an 8 bit byte, and most memory architectures are byte addressable.
The x86 platform uses a byte addressable memory, but employs a standard 64 bit data bus between the memory controller and the physical memory. The data bus transfers up to 8 bytes at a time, corresponding to up to 8 different addresses.
For any single 32 bit address space, this results in 4,294,967,296 addressable bytes.
Now things are going to get interesting.
x86 processors running in 386 protected mode use 32 bit addressing, yet operating systems dating back to Windows 2000 have support for more than 4GiB of physical memory. How is this possible?
The answer is that Intel's microprocessors do not have a straight relationship between the address that the program generates, and the address that is used in the physical memory space.
There are two methods of memory protection on x86 microprocessors: Segmentation, and Paging.
Segmentation takes three different forms depending on whether or not the microprocessor is in real mode (where it's basically just a really fast 8086), protected mode (386 AKA 32 bit mode), or long mode (EM64T aka 64 bit mode). I won't focus on the specifics of segmentation because it's not particularly relevant to this explanation, but I want you to know that it exists and it is always enabled.
Paging was introduced with the 80386 and introduces a "virtual memory space" which creates a mapping between locations in virtual memory, and locations in physical memory. The memory architecture is organized into pages which are typically 4096 bytes in size (4KiB).
The existence of virtual memory is completely transparent to running programs. It affects the operating system and the microprocessor only.
When paging is disabled, only segmentation is used. When paging is enabled, both segmentation and paging are used.
When programs are running, the addressing mode at the register level is called "linear". In 386 mode, the relevant address registers are all 32 bits wide which provides a 4GiB linear address space, and would seemingly limit the system to 4GiB of physical memory.
The x86 microprocessor takes the linear address and passes it through the segmentation unit. If paging is disabled, this generates a physical address which is either 32 bits wide or 64 bits wide depending on the mode of operation (386/EM64T). If paging is enabled, this generates a virtual address, which is either 32 bits wide, or 64 bits wide depending on the mode of operation.
The trick to supporting more than 4GiB of physical memory in a system with a 32 bit linear address space lies in how virtual addresses are mapped to physical addresses. This process, which is performed only when paging is enabled, is called a "page walk".
The page walk process involves traversing what's known as a page table. The physical address of the page table is held inside of a special CPU register called CR3 (Control Register 3).
Recall above how I said that pages are normally 4,096 bytes in length. This corresponds to 2^12. If pages are aligned against each other, they will always start on a 4,096 byte boundary (first page starts at 0, second one at 4096, third one at 8192, and so on) and thus will always have zeroes for the 12 least significant bits of their address. For convenience sake, page tables are themselves stored as pages, and are thus 4096 bytes in length. In a system using 32 bit (4 byte) virtual addresses, a 4096 byte page table is divided into 1024 page (2^10) entries. Each entry in the page table consists of the 20 most significant bits of the first address in each page (the 12 least significant bits will always be zero). The 12 remaining bits are used for flags and other information.
The first step in resolving a virtual address to a physical address starts at what's called the "page directory". This is a page table which has as its entries, more page tables. The 10 most significant bits from the virtual address (bits 22 through 31) are used as an index against the 1024 entries in the page directory. This yields the physical address of another page table. The next 10 bits (bits 12 through 21) are used as an index against the 1024 entries in this page table. This yields the physical address of the desired page. The 12 least significant bits of the virtual address (bits 0 through 11) are used as an offset within this page.
10 bit page directory lookup + 10 bit page table lookup + 12 bit offset results in a mapping between a 32 bit virtual address and a 32 bit physical address
We're not quite done yet though. With the Pentium Pro, Intel introduced a new mode of operation known as "Physical Address Extension". If paging is enabled, PAE can be enabled. PAE slightly changes the way that the page table is laid out. The virtual address remains 32 bits in size, but the physical addresses are all expanded to 64 bits. This means that each 4096 byte page table now holds 512 64 bit address entries rather than 1024 32 bit address entries.
The rest of the process remains more or less the same, except that 9 bits are used for each table index rather than 10 (512 entries rather than 1024). This results in a slack of 2 bits. This is resolved by adding a third level in the page hierarchy called the "page directory pointer table" which has only a 2 bit index and points to 4 page directories. The lookup then looks like so:
2 bit page directory pointer table lookup + 9 bit page directory lookup + 9 bit page table lookup + 12 bit offset results in a mapping between a 32 bit virtual address and a 64 bit physical address
neat huh?
extending this process to native 64 bit virtual addresses adds a 4th layer table in the form 9 + 9 + 9 + 9 + 12 which maps a 48 bit virtual address to a 64 bit physical address.
The end result is that two identical linear or virtual addresses can point to two different locations in physical memory by virtue of traversing different page tables!