First, an "I/O-port" in CPU terminology is not the same as, for example a serial port. It is an addressable entity within the CPU's address space that can be read and/or written to. I/O ports are typically byte, word, or longword sized (which means you simply don't address specific bits, but rather write at least bytes to the port. Single bit setting must be done by reading the port, setting a bit and write back).
Your serial port example would normally break down into a number of I/O ports (like, for example, a port that holds the last received byte, a port that is written to to send a byte and one or more control ports to control the hardware, like setting baud rates or other behavior).
Generally, there's two types of CPU designs related to input/output:
- memory-mapped I/O - Here, the CPU addresses the I/O port just like it would address memory - The I/O port is located within the "normal" memory address space of the CPU, the CPU itself has no specific instructions for I/O, because it will use the very same instructions it uses to access memory. The CPU control bus does normally not have specific lines for I/O port access. Typical examples for CPUs implementing memory-mapped I/O would be Motorola 68000 or MOS 6502.
- Separate I/O address space - Here I/O ports are located outside the "normal" memory address space of the CPU. The CPU also has specific instructions to access I/O ports like
IN
or OUT
. Normally, the CPU control bus also has specific control lines that signal to external hardware that the CPU wants to address within the I/O address space, like IOREQ. Typical examples for CPUs implementing this approach are the Zilog Z80 or Intel x86 processors. Note that CPUs supporting a separate I/O address space are perfectly capable of supporting memory-mapped I/O as well, so there can be mixed-mode approaches.