Hi,
furryfreak wrote:Hi, I've been reading up on canonical address form for quite a while, but one thing remains unclear.
for simplicity's sake, lets say I have just 1k of RAM, and I'm using 16-bit addressing.
If I wrote a byte to the canonical address 0xFFFF, would it be written to the end of memory (0x03FF), or to some random location?
In long mode, the linear address space is split in half with a big hole in the middle. For example, a CPU might support 48-bit linear/virtual addresses, where the highest support bit is extended into the unsupported bits - e.g. the address 0xABCD000000001234 isn't a valid 48-bit address, and the 48th bit is zero, so this zero bit would be extended into the unsupported bits of the address, causing the actual address to be 0x0000000000001234. In the same way, the address 0x1234800000001234 isn't a valid 48-bit address and would become 0xFFFF800000001234 because the 48th bit was set.
An address is "canonical" if the unsupported bits in the address are already set the same as the highest supported bit. For example, 0x0000000000001234 and 0xFFFF800000001234 are canonical addresses; but 0xABCD000000001234 and 0x1234800000001234 are not canonical.
Most (all?) linear/virtual addresses must be canonical or the CPU will generate an exception.
Also note that (for 48-bit linear addressing in long mode) you end up with a linear/virtual address space like this:
0x0000000000000000 to 0x00007FFFFFFFFFFF - canonical addresses (often used for "user space")
0x0000800000000000 to 0xFFFF7FFFFFFFFFFF - non-canonical addresses (unusable)
0xFFFF800000000000 to 0xFFFFFFFFFFFFFFFF - canonical addresses (often used for "kernel space")
Note that this has everything to do with
linear/virtual addressing; and has nothing to do with
physical addresses.
The "end of the physical address space" depends on how many bits the CPUs supports for
physical addresses. You can get this information from CPUID (eax = 0x80000008).
Cheers,
Brendan