Huh!
So you thought you could just detect the amount of RAM your PC had, print the number on screen and live happy with that ? Sorry, dudes, that's not the way things goes.
With the exception of a couple of embedded architectures where the CPU directly communicates with the RAMs, virtually every computer (from the one serving this webpage to the one embedded in your latest pocket game/personnal assistant device) features a memory management unit (MMU) that performs translation between application-friendly (virtual) addresses and physical memory.
There are many reasons to want an MMU. Running multiple programs while giving them the illusion they're alone on the machine is one of them. Being able to abstract the actual physical memory layout may be another (trust me when i tell you that physical layout of embedded ARMs may be a nightmare).
Paging
This is the most common way to achieve memory management: the physical memory is divided in pages of 2^K bytes (typically 4096) and the MMU translates every block of 2^K virtual addresses on one of the pages. For performance reasons, a specific cache holds the translation entries, and the tables used for translation (when defined by the MMU) are hierarchical.
Why "when defined by the MMU" ? because some architecture (including SPARC iirc) do not enforce a specific hardware technique to resolve the mapping: if there's no hit in the cache, an exception is thrown and it's up to the kernel to fill the cache (making room if necessary) and resume operations.
On a x86 PC, a two-level hierarchical table is used (known as "page tables" and "page directory"). Some extensions (common on i686 family) may allow "large pages" of 4MB contiguous memory, taking the place of a whole page table in the directory (and thus skipping a level).
On x86-64, a third level is added (iirc. Don't know much about them, so anyone else is welcome to say the truth).
Segments
Another odd things specific to x86 (and possibly other older architecture that ran MULTICS back in 20th century). An additional context information (the segment register) instructs the MMU to translate a logical address X into another address Y = X + segment_base if X matches a limit constraint. See more about that in the GdtForDummies and similar pages.
How to manage memory
That's detailed in Algorithms and Tips for Memory Management. You hit the wrong page :P
