EAX, AX, and AL are the only registers that data can be moved into or out of, and either a byte-sized immediate value in the instruction or a value in register DX determines which port is the source or destination port of the transfer. Since any general-purpose register can send or receive data to or from memory and memory-mapped I/O devices, memory-mapped I/O uses fewer instructions and can run faster than port I/O. AMD did not extend the port I/O instructions when defining the x86-64 architecture to support 64-bit ports, so 64-bit transfers cannot be performed using port I/O. Memory barriers Since the caches mediate accesses to memory addresses, data written to different addresses may reach the peripherals' memory or registers out of the program order, i.e. if software writes data to an address and then writes data to another address, the cache write buffer does not guarantee that the data will reach the peripherals in that order. Any program that does not include cache-flushing instructions after each write in the sequence may see unintended IO effects if a cache system optimizes the write order. Writes to memory can often be reordered to reduce redundancy or to make better use of memory access cycles without changing the final state of what got stored; whereas, the same optimizations might completely change the meaning and effect of writes to memory-mapped I/O regions. Lack of foresight in the choice of memory-mapped I/O regions led to many of the RAM-capacity barriers in older generations of computers. Designers rarely expected machines to grow to make full use of an architecture's theoretical RAM capacity, and thus often used some of the high-order bits of the address-space as selectors for memory-mapped I/O functions. For example, the 640 KB barrier in the IBM PC and derivatives is due to reserving the region between 640 and 1024 KB (64k segments 10 through 16) for the Upper Memory Area. This choice initially made little impact, but it eventually limited the total amount of RAM available within the 20-bit available address space. The 3 GB barrier and PCI hole are similar manifestations of this with 32-bit address spaces, exacerbated by details of the x86 boot process and MMU design. 64-bit architectures often technically have similar issues, but these only rarely have practical consequences. Examples A simple system built around an 8-bit microprocessor might provide 16-bit address lines, allowing it to address