I/O devices contain registers, and it is these registers which the CPU reads and writes to communicate with the device.
In a system with port-mapped I/O, these registers are written and read using input/output instructions which specify the register by port number. Ports are effectively a separate address space.
In a system with memory-mapped I/O, the registers are written and read using regular copy instructions which specify the device register by a regular address. For this to work, certain addresses are mapped to devices rather than to memory.
Polling: code running on the CPU periodically checks device registers to see if the device needs the CPU to do something. The problem with polling is that doing this constant checking can be wasteful.
Interrupt: A signal sent from an i/o device to the CPU which causes the CPU to jump execution to an address designated in the interrupt table (a table of addresses in a special place in memory). When the interrupt handling code is finished, the processor generally resumes whatever it was doing when the interrupt came in.
Hardware exception: Like an interrupt, but triggered by something in the CPU, e.g. a divide by zero triggers an exception.
