1 - Interrupts und Traps auf x86 [ID:21387]
50 von 157 angezeigt

Normalerweise arbeitet ein System nicht einfach nur vor sich hin, sondern reagiert auf Ereignisse,

beispielsweise von der Peripherie.

Die Erkennung von solchen Ereignissen kann entweder durch regelmäßiges Abfragen in

unserer Software, sogenanntes Polling, geschehen oder wir nutzen Unterbrechungen.

Über eine spezielle Interrupt-Leitung sorgt ein externes Ereignis dafür, dass die reguläre

Abarbeitung in unserem Prozess unterbrochen und eine spezielle Behandlungsroutine ausgeführt

wird.

Im Folgen beleuchten wir dazu Unterbrechungen auf der x86 Architektur und wie deren Behandlung

in Stubs umgesetzt wird.

Unsere Anwendung wird beispielsweise abgearbeitet und sobald ein Unterbrechungsereignis eintritt,

wird der Zustand gesichert und in die Unterbrechungsbehandlungsroutine gewechselt.

Nach der Abarbeitung wird der vorherige Zustand wiederhergestellt und die Abarbeitung der Anwendung transparent fortgesetzt.

Aber was ist der Zustand der Anwendung, welcher bei einer Unterbrechung auf jeden Fall gesichert werden muss?

Mindestens natürlich die aktuelle Position des Instruktionszeigers, zu dem danach wieder zurückgekehrt werden muss.

Diesen sichert die CPU vor dem Einsprung in die Behandlungsfunktion automatisch auf dem Stack,

zusammen mit dem Statusregister Flex und historisch bedingt dem Codesegmentregister.

Um nun aus der Behandlungsfunktion wieder zurückzukehren, muss die Instruktion IRED bzw. bei 64-bit IRED-Q aufgerufen werden,

welche die Werte vom Stack wieder in die Register liest und somit an der vorherigen Position des Instruktionszeigers fortsetzt.

Diese Rückkehrinstruktion verwenden wir auch am Ende unserer Unterbrechungsbehandlung,

welche wir somit in Assembler schreiben.

Da wir jedoch aus guten Gründen eine Hochsprache bevorzugen, wollen wir den Assemblerteil nur so kurz wie möglich halten

und fügen dort einen Aufruf zu der Hochsprachenfunktion Interrupt Handler ein,

welche wir im Falle von Stubs in C++ implementieren.

Interrupt Entry ist somit nur der Einsprungspunkt zu der eigentlichen Unterbrechungsbehandlung.

Leider funktioniert der Codenomen beim Übersetzen noch nicht so wie gewünscht.

Es wird stattdessen eine fehlende Referenz mit dem Funktionsnamen gemeldet.

Wenn wir uns die übersetzte C++-Datei, in der wir diese Interrupt Handlerfunktion implementiert haben,

genauer anschauen, erkennen wir, dass dort nur ein seltsames Symbol namens

unterstrich z17 interrupt unterstrich handler v existiert. Wieso?

Nun, in C++ kann es durch Funktionsüberladung vorkommen, dass es mehrere Funktionen mit demselben Namen,

aber unterschiedlichen Parametern gibt.

Um dieses Problem zu adressieren, gibt es das Name-Mangling,

in welchem eben der Parameter mit verwurschtet wird.

In unserem Fall ist es das v am Ende, das für void kein Parameter steht.

Die 17 am Anfang steht übrigens für die Länge des Funktionsnamens.

Entsprechend können hier auch Namespaces mit einbezogen werden.

Da die genaue Umwandlung nicht im C++-Standard spezifiziert wurde und compiler-spezifisch ist,

auch wenn es sich inzwischen ein De-Faktor-Standard entwickelt hat,

können wir mit dem Schlüsselwort externC eine Verknüpfung als C-Symbol erzwingen,

wodurch nun der Symbolname unseren Erwartungen entspricht und von unserer Assembler-Routine aufgerufen werden kann.

Das bedeutet, unsere Behandlungsroutine funktioniert.

Nun, solange unsere Anwendung keine Register verwendet.

Von der CPU werden nur die Instruktionszeige RIP und das Statusregister RFLEX gesichert,

aber unsere Anwendung verwendet sehr wahrscheinlich General-Purpose-Register wie rax und rbx.

Um die Sicherung müssen wir uns entweder im Assembler-Code selbst kümmern oder aber auf den Übersetzer setzen.

Und da gilt es sich generell zu einigen, wie beim Aufruf von Funktionen die Register gesichert werden sollen.

Prinzipiell hat man mehrere Möglichkeiten.

Erstens, die aufrufende Funktion sichert alle Register, deren Inhaltssiehmanschluss noch benötigt.

Zweitens, die aufgerufene Funktion sichert alle Register, welche sie nachfolgend verändern wird.

Oder drittens, ein Hybrid aus beiden Varianten, ein Teil vom Aufrufer, der andere Teil von der aufgerufenen Funktion,

Teil einer Videoserie :
Teil eines Kapitels:
Interrupts

Zugänglich über

Offener Zugang

Dauer

00:16:15 Min

Aufnahmedatum

2020-07-28

Hochgeladen am

2020-10-16 18:06:30

Sprache

de-DE

Unterbrechungen auf der x86 Architektur für Aufgabe 2 der Lehrveranstaltung Betriebssysteme.

Folien und Transkript zum Video.

Tags

betriebssysteme interrupts operating systems stubs
Einbetten
Wordpress FAU Plugin
iFrame
Teilen