Inhaltsverzeichnis
  Übersicht Kapitel 2
  2.4 Das Operationswerk      2.6 Der Registersatz

2.5 Das Adreßwerk

Das Adreßwerk (Address Unit AU, Address Generation Logic) hat die Aufgabe, nach den Vorgaben des Steuerwerks aus den Inhalten bestimmter Speicherzellen und Register die Adresse eines gewünschten Befehls oder Operanden zu bilden. Es ist sicher die interne Komponente der Mikroprozessoren, die in den letzten Jahren den stärksten Entwicklungsschüben unterworfen war. Bei den älteren 8-bit-Prozessoren wurde diese Adreßberechnung zum großen Teil noch von der ALU des Operationswerkes vorgenommen, so daß bei ihnen ein spezielles Adreßwerk entfiel. Jedoch besaß bereits Mitte der 70er Jahre der µP 2650 von Valvo einen speziellen Adreßaddierer (Offset Adder). Seitdem sind viele Funktionen zu den Aufgaben des Adreßwerkes hinzugekommen. Dadurch wird es möglich, die Adreßberechnung parallel zu den Aktivitäten des Operationswerkes durchzuführen und somit die Verarbeitungsgeschwindigkeit des Prozessors wesentlich zu erhöhen. Moderne Prozessoren, die (intern) eine Harvard-Architektur aufweisen, besitzen zwei Adreßwerke für die gleichzeitige Berechung einer Befehls- und einer Operandenadresse. DSPs verfügen sogar über drei Adreßwerke, da sie in jedem Taktzyklus neben einem Befehl auch noch zwei Operanden selektieren müssen.
Zu den Aufgaben des Adreßwerks bei Hochleistungsprozessoren gehört insbesondere die Verwaltung eines virtuellen Speichers. Vereinfachend gesagt, geht es dabei um die Umwandlung von logischen Programmadressen in physikalische Speicheradressen. Bei den älteren Prozessortypen wurde diese Aufgabe von speziellen Bausteinen (Memory Management Unit MMU) vorgenommen. Die neueren 16/32-bit-Prozessoren besitzen jedoch eine (oder mehrere) auf dem Chip integrierte MMU. Um dieses Kapitel inhaltlich nicht zu überfrachten, werden wir auf die MMUs nicht ausführlich eingehen. Hier wollen wir nur erwähnen, daß zur virtuellen Speicherverwaltung das Adreßwerk auf eine große Anzahl von Registern und Tabellen zugreifen muß, und am Ende dieses Abschnitts eine vereinfachte Darstellung bringen.
Bild 2.5-1 zeigt ein sehr einfaches Beispiel für ein Adreßwerk, zusammen mit den angeschlossenen Komponenten des µPs. In ihm sind, wie angekündigt, alle Komponenten zur Speicherverwaltung nur durch ihre Register und Tabellen repräsentiert.
Das Adreßwerk besteht im wesentlichen aus einem Adreßaddierer. Als "Akkumulatoren" dienen diesem Addierer wahlweise der Programmzähler oder der Adreßpuffer, je nachdem, ob die Adresse des nächsten Programmbefehls oder eines Operanden berechnet werden muß. Wie bereits gesagt, enthält der Programmzähler (Program Counter), der auch Befehlszähler genannt wird (Instruction Pointer - IP), stets die Adresse der Speicherzelle, in der der nächste auszuführende Befehl (oder Befehlsteil) liegt. Beim sequentiellen, nicht durch Sprünge oder Verzweigungen unterbrochenen Programmablauf wird der Programmzähler mit jedem Befehl (bzw. Befehlsteil) nur um 1 erhöht. (Dies ist im Bild 2.5-1 durch das Symbol '+1' angedeutet.) Zur Realisierung von Sprüngen und Verzweigungen wird der Programmzähler mit der neuen Programmadresse geladen. Wird durch eine falsch berechnete Sprungadresse nicht zu einem neuen Befehl, sondern statt dessen in einen Datenbereich des Speichers verzweigt, so führt das in der Regel zu unvorhersehbaren Auswirkungen ("Der µP läuft in den Wald"). Die für die Ausführung eines Maschinenbefehls benötigten Operanden werden durch den Adreßpuffer selektiert. Der Adreßpuffer wird vom Adreßwerk mit der Adresse des Operanden geladen, die nach bestimmten fest vorgegebenen Verfahren berechnet wird. Diese als Adressierungsarten bezeichneten Verfahren werden Sie im Abschnitt 3.3, kennenlernen.
Das Ergebnis der Adreßberechnung wird über die Systembusschnittstelle an die Peripheriekomponenten des Prozessors ausgegeben. Bei Prozessoren mit von-Neumann-Architektur schaltet ein Multiplexer in der Schnittstelle entweder den Programmzähler (zum Zugriff auf den nächsten Befehl) oder den Adreßpuffer (zum Zugriff auf den nächsten Operanden) nach außen. Bei Prozessoren mit Harvard-Architektur werden beide Registerwerte über getrennte Adreßbusse nach außen gegeben (gestrichelte Pfeile im Bild).
Die Werte der Akkumulator-Register werden dem Addierer zugeführt und dort mit weiteren Eingabewerten zur Adreßberechnung verknüpft. Diese Eingabewerte können einerseits aus dem allgemeinen Registersatz entnommen werden. Die Adreßwerke von DSPs zur Berechnung von Operandenadressen (Data Address Generator/Unit) verfügen meist über separate Registersätze mit jeweils bis zu 24 Adreßregistern. Andererseits können die Eingabewerte aber auch aus dem Datenbuspuffer in der Systembusschnittstelle des Prozessors kommen. In diesem Fall handelt es sich um eine im Befehl angegebene absolute Adresse oder eine Adreßdistanz zu einer Basisadresse im Registersatz.
Die mit Skalierung bezeichnete Komponente existiert hauptsächlich bei 32-bit-Prozessoren. Sie erlaubt es, einen Operanden wahlweise mit den Werten 1, 2, 4 oder 8 zu multiplizieren. Da es sich bei den Eingabewerten zur Adreßberechnung häufig um Adressen oder Adreßdistanzen (Offsets) von Speicherzellen handelt, die z.B. in einem Register stehen, kann man sukzessiv auf Datenwörter der Länge 1, 2, 4 oder 8 byte zugreifen, indem man den Registerwert vor der Skalierung jeweils um 1 erhöht bzw. erniedrigt. Dies wird bei den im Abschnitt 3.3 dargestellten Adressierungsarten ausgenutzt.


Bild 2.5-1:  Aufbau eines einfachen Adreßwerks


Bei Prozessoren ohne virtuelle Speicherverwaltung bildet das Ergebnis der bisher beschriebenen Adreßberechnung die physikalische Speicheradresse des Befehls oder Operanden. Bei virtueller Speicherverwaltung liegt hingegen zunächst eine logische (virtuelle) Adresse vor, die durch mehrfachen Zugriff auf Register und Tabellen der Speicherverwaltung erst in eine physikalische Adresse umgewandelt und danach auf den Adreßbus gegeben wird. Wie bereits angekündigt, soll anhand von Bild 2.5-2 nur kurz die Adreßumwandlung der virtuellen Speicherverwaltung vereinfacht dargestellt werden.


Bild 2.5-2:  Adreßumwandlung bei virtueller Speicherverwaltung


Unser hypothetischer Prozessor besitze einen 24-bit-Adreßbus - und damit einen 16 Mbyte umfassenden physikalischen Adreßraum. Dieser wird durch die Speicherverwaltung in Segmente mit maximal 64 kbyte unterteilt. Die im Programm angegebenen virtuellen (logischen) Adressen sind jedoch jeweils 30 bit lang, so daß der virtuelle Adreßraum 1 Gbyte groß ist. Die virtuellen Adressen bestehen aus einer 14 bit langen Segmentnummer und einem 16-bit-Offset, der die Lage eines Datums in dem adressierten Segment angibt.
Das Betriebssystem legt für jedes neue Programm eine eigene Tabelle im Hauptspeicher an, in der die Startadressen aller Segmente, die zu diesem Programm gehören, eingetragen werden. Die Anfangsadresse dieser Tabelle wird in ein Basisregister eingetragen.
Bei der Adreßumsetzung wird die 14-bit-Segmentnummer in der virtuellen Adresse durch die Speicherverwaltungseinheit (MMU) zu dem Inhalt des Basisregisters addiert. Das Ergebnis zeigt auf einen Eintrag in der Segmenttabelle, aus dem die Anfangsadresse des angesprochenen Segments entnommen wird. Die Addition des Offsets in der virtuellen Adresse zu dieser Anfangsadresse ergibt schließlich die gesuchte physikalische Speicheradresse.

Selbsttestaufgabe S2.5-1:  (–>Lösungsvorschlag)

Im Abschnitt 3.3 werden Sie die folgende Schreibweise für eine indizierte Adressierungsart mit Post-Inkrementierung kennenlernen:

<Offset>(B0)(I0)+ .

Die dadurch vorgegebene Berechnungsvorschrift für die Operandenadresse lautet:

"Addiere den Inhalt des (Basis-)Registers B0, des (Index-)Registers I0 sowie den im Befehl angegebenen Offset. Erhöhe nach dem Zugriff zum Operanden den Inhalt des (Index-)Registers I0 um 1".

Geben Sie alle Teilschritte an, die zur Ausführung der Adreßberechnung nötig sind. Nehmen Sie dabei an, daß die Inkrementierung des (Index-)Registers I0 durch das Adreßwerk vorgenommen werden muß.


  Inhaltsverzeichnis
  Übersicht Kapitel 2
2.4 Das Operationswerk        2.6 Der Registersatz