They use different address spaces and different instructions.
In practical terms:
With memory mapped IO, IO ports are addressed like memory cells and they
can be accessed by the same instructions, while with PORT IO, access to
IO ports is done through special instructions using non-memory-addresses.
This is obvious when programming e.g. in C: with memory mapped IO, you
just address the IO port like a memory cell through a pointer while
you'll need some external function or inline asm code with port IO.
I.e. if you want to read the contents of I/O port at address 0x1234,
with memory mapped IO, you could just do something like
status = *(unsigned char *)0x1234;
you can also set bits in one instruction
*(unsigned char *)0x1234 |= 1;
You can also overlay io regions with structs that then map to the
With port IO, you have to use a special instruction:
status = inb(0x1234);
Motorola processors (eg m68k), DEC (PDP11, VAX), MIPS (Rx000), NatSemi
(ns32k) use(d) memory mapped IO while Intel processors (ix86) use port IO.
When using memory mapped IO, you need to take special care to avoid
optimizations made by the compiler (some compilers will optimize
repeated writes to the same address unless the location is declared
"volatile") and/or the processor (it must not cache accesses to IO
regions, write-combine or detect multiple writes to the same address,
this sometimes requires inserting special instructions which explicitly
flush a write buffer).
Josef Mlers (Pinguinpfleger bei FSC)
If failure had no penalty success would not be a prize
-- T. Pratchett