The system bus connects the CPU with the main memory and is
separate from the buses connecting the CPU with the system's
hardware peripherals. Collectively the memory space that the hardware peripherals
exist in is known as I/O space. I/O space may itself be further subdivided, but we
will not worry too much about that for the moment. The CPU
can access both the system space memory and the I/O space memory, whereas the
controllers themselves can only access system memory indirectly and then only with
the help of the CPU.
For example the floppy disk controller can only see the address space that its
control registers are in (ISA), and not the system memory
Typically a CPU will have separate instructions for accessing the
memory and I/O space. For example, there might be an instruction that means
"read a byte from I/O address 0x3f0 into register X".
This is exactly how the CPU controls the system's hardware
peripherals, by reading and writing to their registers in I/O space.
Where in I/O space the common peripherals (IDE controller,
serial port, floppy disk controller and so on) have their registers has been set by
convention over the years as the PC architecture has developed. The I/O space
address 0x3f0 just happens to be the address of one of the serial port's
(COM1) control registers.