Die einfachste Methode, Eingangs-Ports zu
verwenden, ist das sogenannte Polling,
bei dem das Programm regelmäßíg alle
in Frage kommenden Ports überprüft,
als würde es sie der Reihe nach fragen:
"Hast du Daten für mich?"
Dieses aktive Prüfen der Ports vergeudet Zeit,
es macht das Programm langsamer, denn
jede Abfrage benötigt ein paar Codezeilen.
Deswegen können CPUs Interrupt-Register
(engl. "interrupt" = "unterbrechen") setzen,
die einige interessante Aktionen auslösen,
wenn ihr jeweiliger Eingabe-Port Daten sendet.
Sie unterbrechen das laufende Programm,
heben es gewissermaßen aus den Angeln,
und speichern seinen Programmzeiger in einem
besonderen Speicherbereich, dem Interrupt-Stack,
unter der nächsten freien ungenutzten Adresse.
Dann setzen sie den Programmzeiger auf ihre
programmierte Interrupt-Handler-Adresse und
lassen den Programmzeiger wieder laufen.
Der Handler-Code für den Interrupt (Event/Ereignis)
arbeitet mit den Daten des Eingangs-Ports, und
wenn er damit fertig ist (fachsprachlich: wenn er
"den Interrupt bedient" hat), setzt er den Befehl
zur Rückkehr (engl. "return").
Beim Rückkehr-Befehl wird der zuletzt auf dem
Interrupt-Stack abgelegte Programmzeiger wieder
als der aktuelle Programmzeiger geladen,
der Stack wird um ein Element verkürzt und
das ursprüngliche Programm läuft weiter.
Damit braucht das Programm nun keinen Code
mehr für das Polling zu verschwenden. Es teilt
allen in Frage kommenden Eingabe-Ports nur noch
je ein einziges Mal mit, wo ihr jeweiliger
Interrupt-Handler-Code liegt (seine Adresse
im Programmspeicher), fertig.
Eine besondere in diesem Kontext interessante
E/A-Gruppe sind die sogenannten Timer,
also Zeitgeber, die einen Ereignis-Interrupt
alle soundso viele gewünschte (programmierte)
Prozessortakte auslösen.
Wie alle Interrupt-Register lassen sich auch
Tier vom Programm wieder löschen, etwa gleich
als erste Aktion in einem Timeout-Handler
(der ein Ereignis nur einmal nach einer
gewünschten Zeitspanne auslöst).