Adressierung (Datenverarbeitung)
aus Wikipedia, der freien Enzyklopädie
Die Adressierung (auch Adressierungsart oder -modus) beschreibt den vom Programm vorgegebenen Weg, wie ein Prozessor die Operanden für eine Rechenoperation im Speicher lokalisiert und den Speicherort für das Ergebnis angibt. Die Zuführung der Adressen zum Speicher erfolgt dabei über den Adressbus, während die Operanden aus den adressierten Speicherplätzen über den Datenbus dem Rechenwerk zugeführt werden. Je ‚lückenloser‘ die Operanden im Speicher abgelegt sind, desto schneller kann der Datenzugriff erfolgen. Bei idealer Speicherausrichtung erfolgt der Zugriff besonders schnell, je nach Prozessorarchitektur beispielsweise innerhalb eines Prozessortaktes.
Man unterscheidet verschiedene Adressierungsarten. Sie sind ein Aspekt einer Befehlssatz-Architektur der meisten Hauptprozessor-Designs. Die verschiedenen Adressierungsmodi, die innerhalb einer gegebenen Befehlssatzarchitektur definiert sind, bestimmen, wie die Instruktionen der Maschinensprache den oder die Operanden jeder einzelnen Instruktion identifizieren. Ein Adressierungsmodus spezifiziert, wie die tatsächliche (physische) Speicheradresse eines Operanden berechnet werden soll, mithilfe der Informationen, die in Registern gespeichert sind und/oder Konstanten innerhalb des Maschinenbefehls.
Inhaltsverzeichnis |
[Bearbeiten] Fallstricke
Man beachte, dass es keine generell akzeptierte Art und Weise der Namensgebung für die unterschiedlichen Adressierungsmodi gibt. Insbesondere vergeben teilweise verschiedene Autoren oder auch Hardwarehersteller unterschiedliche Namen für den gleichen Adressenmodus, oder auch den gleichen Namen für unterschiedliche Modi. Des weiteren kann ein Adressierungsmodus, der in der einen Architektur als ein einzelner Modus behandelt wird, für eine Funktionalität stehen, die in einer anderen Architektur von zwei oder mehr Modi abgedeckt wird.
Bei der Unterscheidung der verschiedenen Adresstypen ist folgende Namensgebung weit verbreitet: Die grundlegende Unterscheidung ist die zwischen Maschinenadressen bzw. physischen Adressen einerseits und logischen bzw. programmseitigen Adressen andererseits. Maschinenadressen werden auch oft reale Adressen genannt. Logische Adressen werden wiederum in absolute, relative, indirekte und symbolische Adressen unterteilt, wobei man allerdings verschiedene genaue Charakterisierungen, Abgrenzungen und Überschneidungen findet.
[Bearbeiten] Typische Adressierungsarten eines Prozessors
Im einfachsten Fall sind die einzelnen Speicherplätze des Speichers von 0 an durchnummeriert (linearer Adressraum). Eine Adresse stellt dann die Nummer eines bestimmten Speicherplatzes dar. Die Register eines Prozessors werden im Regelfall ebenfalls durchnummeriert.
Man unterscheidet je nach Rechnerarchitektur verschiedene Adressierungsarten:
- Registeradressierung. Ziel der Adresse ist ein Register im Prozessor. Die Adresse (Nummer) des Registers wird direkt angegeben.
- Unmittelbare Adressierung. Die Operanden sind Bestandteil des Befehls.
- Absolute Adressierung. Ziel der Adresse ist eine Speicherzelle im Hauptspeicher. Die Adresse der Speicherzelle wird direkt angegeben (Referenzstufe 1).
- Relative Adressierung. Ziel der Adresse ist eine Speicherzelle im Hauptspeicher. Die übergebene Adresse wird zum Wert des Spezialregisters PC (program counter) als Offset addiert (Referenzstufe 1).
- Indirekte Adressierung. Die übergebene Adresse verweist auf ein Register (oder beim 6502 auf ein Paar Bytes in dessen Zeropage), in dem wiederum die Adresse des eigentlichen Ziels im Hauptspeicher abgelegt ist. Durch Substitution wird die indirekte Adresse in die intendierte Registeradresse transformiert (Referenzstufe 2).
- Indizierte Adressierung. Übergeben werden zwei Adressen. Die erste verweist auf ein Register, in dem ein Wert abgelegt ist. Dieser Wert wird als Offset zur zweiten Adresse addiert, das Ergebnis ist die Adresse des Ziels im Hauptspeicher.
Da normalerweise viel weniger Register als Speicherplätze existieren, benötigen Registeradressen viel weniger Stellen als Hauptspeicheradressen. (Beispiel: Bei einem System mit Prozessor mit 16 Registern sowie 4 GiB Speicher benötigt eine Registeradresse 4 Bit, während eine Hauptspeicheradresse 32 Bit benötigt.) In der Maschinensprache werden Registeradressen meist zusammen mit dem Befehlscode in einem Speicherwort gespeichert – stehen mithin dem Prozessor ohne weitere Speicherzugriffe zur Verfügung – während der Prozessor für die Übermittlung jeder Hauptspeicheradresse weitere Speicherzugriffe – und damit Ausführungszeit – benötigt.
[Bearbeiten] Unmittelbare Adressierung
Der oder die Operanden sind Bestandteil des Befehls, gespeichert im Befehlscode selbst oder in den Speicherwörtern, die im Speicher unmittelbar nach dem Befehlscode folgen.
# Lade das Indexregister mit dem Wert 22 (101102) (nicht mit dem Inhalt von Speicherplatz 22) load index, 10110
[Bearbeiten] Absolute oder direkte Adressierung
Bei dieser Adressierungsart wird die Speicheradresse bei jedem Befehl direkt und vollständig angegeben. Die Gesamtheit der möglichen Adressen bildet den Adressbereich dieser Adressierungsart.
# Addiere den Inhalt der Adressen 22 (= 101102) und 6 (= 001102) und speichere das Ergebnis in Adresse 1 (= 000012) add 10110, 00110, 00001
Häufig können nur zwei Adressen angegeben werden, dabei wird dann das Resultat dort gespeichert, wo vor Ausführung der Addition einer der Operanden stand (Akkumulator-Prinzip). Diese Adressierungsart wird heute nur noch in Integrierten Schaltkreisen und eingebetteten Systemen mit wenig Speicherplatz angewandt. So benötigt in einem Rechner mit einem 32 Bit breitem Adressbus solch einfacher Additionsbefehl allein für die Adressangaben 96 Bit. Zur Verringerung des Speicheraufwands werden zwei weitere Möglichkeiten der Adressierung verwendet.
[Bearbeiten] Indizierte und relative Adressierung
Beide Adressierungsarten verwenden ein Register zur Speicherplatzersparnis. Bei der indizierten Adressierung wird das so genannte Indexregister zu jeder Adressangabe addiert.
# Addiere den Inhalt der Adressen 22 (Index+002) und 23 (Index+012) und speichere das Ergebnis in Adresse 24 (Index+102) load index, 10110 add 00, 01, 10
Der Trick besteht darin, dass die relativen Adressen weniger Stellen haben. So kann der Befehl mit relativen Adressen von beispielsweise 8 Bit (8 Binärstellen) einen Bereich von nur 28=256 Speicherplätzen, relativ zur im Indexregister gegebenen Speicheradresse, ansprechen. Dafür verringert sich der Speicherbedarf für die Adressen von 96 Bit auf 24 Bit. (Wobei jedoch ggf. das Indexregister zunächst mit dem passenden Wert geladen werden muss.)
Für das Durchlaufen von Speicherbereichen ist dies hervorragend geeignet. Bei der relativen Adressierung speichert das Register die so genannte Basisadresse und die Adressen für die Befehle werden nur noch als Offset angegeben. Dabei sind negative und positive Offsets möglich.
# Basis ist 65536 (100000000000000002). Addiere den Inhalt der Adressen 65540 (Basis+01002) # und 65549 (Basis+11012) und speichere das Ergebnis in 65537 (Basis+00012) load index, 10000000000000000 add 0100, 1101, 0001
Da ein Rechner mehr als ein Register hat, muss ein jeder Befehl dieser Art eine Registeradresse enthalten (meist eine 4-bit- oder 8-bit-Angabe), die das Register angibt, das als Index-Register zu benutzen ist. Diese Registeradresse ist in den Beispielen oben nicht dargestellt.
Die relative Adressierung verläuft ähnlich, allerdings wird statt des Indexregisters der Befehlszähler (program counter, PC) benutzt. Die Adressierung erfolgt als nicht relativ zu einer im Indexregister angegebenen Adresse, sondern relativ zum Befehlszähler, d. h. der Speicherstelle, die den Befehl selbst enthält.
Normalerweise muss sich der Programmierer nicht um die Relativ-Adressen kümmern, da meist der Assembler oder Compiler die Berechnung der Offsets übernimmt.
Aber auch diese Adressierungsarten sind für heutige Rechner nicht mehr ausreichend.
[Bearbeiten] Virtuelle Adressierung
Hier werden Werkzeuge zur Adressierung beschrieben, die das Betriebssystem zur Verfügung stellt.
Betriebssysteme verwenden die Virtuelle Adressierung, um Programme ausführen zu können, die mehr Speicherplatz benötigen, als an physischem Arbeitsspeicher im RAM überhaupt zur Verfügung steht. Der gesamte zur Verfügung stehende Speicherplatz wird als Virtueller Adressraum bezeichnet und der Zugriff auf die darin enthaltenene Adressen ist die virtuelle Adressierung. Das jeweilige Betriebssystem verwendet eine Virtuelle Speicherverwaltung, die sich einer Memory Management Unit bedient, um Teile des Programms auf die Festplatte auszulagern und ggf. in den Arbeitsspeicher zu laden, falls sich eine gewählte Adresse außerhalb des im RAM befindlichen Adressraums befindet. Die Angabe der Adressen erfolgt dabei entweder direkt, relativ, indiziert oder auch symbolisch.
[Bearbeiten] Symbolische Adressierung
<Im Folgenden werden Werkzeuge zur Adressierung beschrieben, die so oder ähnlich vom Entwicklungssystem (Assembler) zur Verfügung gestellt werden.>
Symbolische Adressierung erlaubt es dem Programmierer Adressen mit Namen, so genannten Mnemonics zu belegen, um Fehler bei der Angabe der Adresse zu vermeiden.
#Addiere die Adresse 65539 und 65549 und speichere das Ergebnis in 65537 define operand1, 10000000000000011 define operand2, 10000000000001101 define ergebnis, 10000000000000001 add operand1, operand2, ergebnis
[Bearbeiten] Adressierung von Arrays
Eine spezielle Form der Adressierung erfordern mehrdimensionale Datenfelder, wie zum Beispiel Tabellen oder Assoziative Arrays, und die Umrechnung von Feldreferenz in Speicheradresse. Ausführlich behandelt dieses Thema der Artikel Array.
[Bearbeiten] Siehe auch
- Adressierung (allgemein)