Unterschied zwischen Interrupt-Adresse und Interrupt-Vektoradresse verstehen

In meinem Grundstudium wurde mir 8051 beigebracht, und in Unterbrechungen hatte mein Professor gesagt, dass bei Interrupt SP auf die fest codierte Adresse zeigt und das Programm diese Anweisungen ausführt. Aber zwischen zwei Adressräumen ist nur, wo ich Interrupt-Behandlungscode schreiben kann und ich mehr als als verfügbares Byte geschrieben habe, wird es die nächsten Interrupt-Anweisungen überschreiben.

Wenn ich mir jetzt das Atmega- oder LPC2148-Datenblatt ansehe, hat es eine Interrupt-Vektoradresse und ich gehe davon aus, dass es auf eine Adresse zeigt, an der Anweisungen für Interrupt-Handhabungsanweisungen geschrieben sind (nicht genau an diesen Adressen). Sind meine Annahmen richtig?

PS Da ich mich in einem Netz mit geringer Bandbreite befinde, kann ich keine Links zum Datenblatt bereitstellen. Würde das machen wenn ich zurück bin.

Ich glaube, deine Vermutung ist richtig
In Ihrem Satz "SP zeigt auf ..." meinten Sie wahrscheinlich "PC", oder?
jede CPU-Architektur ist möglicherweise nicht gleich. Mindestens drei verschiedene Methoden existieren. Einige verwenden eine hartcodierte PC-Adresse, andere verwenden eine 1-Byte- oder 2-Byte-Sprungtabelle oder eine ISR-Nachschlagetabelle oder eine dynamische Sprungadresse. ISR., IRQ-Dokumentation definiert, was verwendet wird.
@dim Zeigt der Stapelzeiger nicht auf die Adresse, die in den PC geladen wird?
@TonyStewart.EEsince'75 Diese Sprungadressen nennen sie Interrupt-Vektortabelle und fest codierte Adressen sind Interrupt-Adressen in Bezug auf die Terminologie, oder hat jede Architektur ihre eigene?
@MaNyYaCk Nein, der Stapelzeiger (SP) ist die Adresse, an die die Mehrzweckregisterwerte geschoben/abgesprungen werden. Sie hat nichts mit dem Programmzähler (PC) zu tun, der die Adresse der nächsten abzurufenden Anweisung anzeigt.

Antworten (3)

Die Interrupt Service Routine (ISR) ist das Programm, das ausgeführt werden soll, wenn ein Interrupt auftritt.

Einige CPU-Architekturen haben feste Adressen, an denen die CPU einen Subroutinenaufruf ausführt. Dies gilt für den MCS-51 (8051). An dieser Adresse muss der ISR beginnen. Es ist nicht ungewöhnlich, einfach einen Jump-Befehl an diese Adresse zu setzen, der die CPU zum Rest der ISR an einer anderen Stelle im Speicher bringt.

Andere CPU-Architekturen verwenden Interrupt-Vektoren. Der Vektor ist ein Speicherplatz, an dem die Adresse des ISR zu finden ist. Der Ort des Vektors ist der CPU bekannt, entweder indem er fest ist oder in Verbindung mit einem speziellen CPU/Hardware-Register. Wenn die CPU den Interrupt bedient, liest sie einen Vektorwert aus dem Speicher und führt einen Subroutinenaufruf für den Vektorwert aus. Dies gilt für die ARM-, 6502- und 68000-Familie. Externe Hardware kann bei der Spezifizierung des bestimmten Vektors zur Verwendung innerhalb einer Vektortabelle eine Rolle spielen, aber das Prinzip gilt immer noch.

Die Behandlung von Interrupts in der 8051-CPU und in der ARM-CPU scheint Ihnen also unterschiedlich zu sein, da sie grundlegend unterschiedliche Schemata zum Auffinden der Adresse des ISR verwenden. Aber diese beiden Methoden (fest codierte Adresse versus Vektor im Speicher) sind so ziemlich die einzigen Schemata, denen Sie in allen CPUs begegnen werden, die Sie sehen werden.

(Es gibt die gelegentliche Kuriosität, wie der Z80 im Interrupt-Modus 0, wo er erwartet, eine Anweisung von externer Hardware zu lesen, die ihn zum ISR bringt, aber ich würde Ihr Wasser nicht mit diesem Zeug trüben, während Sie den Dreh raus haben Von allem.)

Interrupt-Vektoren sind die Adressen auf der MCU, von wo aus die Adresse der Interrupt-Service-Routine beim Auftreten eines spezifizierten/beabsichtigten Ereignisses in den Programmzähler geladen würde. Beispielsweise kann der Überlauf des Timer-Zählers einen Interrupt verursachen, wenn er dafür konfiguriert ist. Wenn diesem Timer-Modul eine Interrupt-Service-Routine (ISR) zugeordnet ist, würde diese genauso aufgerufen werden wie jede normale Task-Umschaltung (mit Ausnahme einiger Ausnahmen).

Ihr Verständnis ist teilweise richtig. Wenn ein Interrupt auftritt, wird der aktuelle Ausführungsstatus im Stapelzeiger gesichert und der Programmzähler mit der Adresse des ISR geladen, die grundsätzlich in der Interrupt-Vektoradresse gespeichert ist.

Die Programmadresse für einen Interrupt-Vektor ist die Programmadresse, zu der die CPU springt, wenn ein Interrupt ausgelöst wird. Es ist genau wie bei anderen Programmadressen. Im Fall von AVR unterscheiden sich benachbarte nur durch 1 Anweisung, was bedeutet, dass Sie nur 1 Anweisung für jeden Interrupt-Vektor platzieren können, wenn Sie alle verwenden möchten. Normalerweise ist es eine rjmpAnweisung an den Rest des Programms, der den Interrupt behandelt.

Wenn Sie eine Hochsprache wie C verwenden, können Sie den Compiler anweisen, das für die Behandlung des Interrupts zuständige Programm an der richtigen Stelle abzulegen. So geht's: http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html

Was mich in diesem Fall verblüfft, ist die eindeutige Aussage der AVR-Dokumentation: „Beachten Sie, dass das Statusregister beim Eintritt in eine Interrupt-Routine nicht automatisch gespeichert und bei der Rückkehr aus einer Interrupt-Routine nicht wiederhergestellt wird. Dies muss vom Anwendungsprogramm gehandhabt werden.“ Daher muss ich Status speichern, dorthin springen, wo sich die ISR befindet, den Status wiederherstellen und RETI? Wie macht es das alles in einer Anweisung?
"Wie macht es das alles in einer Anweisung?" - tut es nicht. Sie müssen den Status manuell speichern und wiederherstellen, und da dies das Lesen und Schreiben einer E/A-Position beinhaltet, müssen Sie mindestens ein anderes Register speichern und wiederherstellen (es sei denn, Sie widmen es nur der ISR-Verwendung). Dies erfordert mehrere Anweisungen, daher ist die einzige nützliche Anweisung, die Sie an der Vektoradresse platzieren können, ein Sprung (es sei denn, nachfolgende Vektoren werden nicht verwendet, dann können Sie sie vom Code überlaufen lassen).