Adressierungsmodus – Wikipedia

before-content-x4

Adressierungsmodi sind ein Aspekt der Befehlssatzarchitektur in den meisten CPU-Designs (Central Processing Unit). Die verschiedenen Adressierungsmodi, die in einer gegebenen Befehlssatzarchitektur definiert sind, definieren, wie die Maschinensprachenbefehle in dieser Architektur die Operanden jedes Befehls identifizieren. Ein Adressierungsmodus gibt an, wie die effektive Speicheradresse eines Operanden unter Verwendung von Informationen berechnet wird, die in Registern und / oder Konstanten enthalten sind, die in einem Maschinenbefehl oder anderswo enthalten sind.

after-content-x4

In der Computerprogrammierung sind Adressierungsmodi in erster Linie für diejenigen von Interesse, die in Assemblersprachen schreiben, und für Compiler-Autoren. Für ein verwandtes Konzept siehe orthogonalen Befehlssatz, der sich mit der Fähigkeit eines Befehls befasst, einen beliebigen Adressierungsmodus zu verwenden.

Vorsichtsmaßnahmen[edit]

Beachten Sie, dass es keine allgemein akzeptierte Möglichkeit gibt, die verschiedenen Adressierungsmodi zu benennen. Insbesondere können verschiedene Autoren und Computerhersteller demselben Adressierungsmodus unterschiedliche Namen oder unterschiedlichen Adressierungsmodi dieselben Namen geben. Darüber hinaus kann ein Adressierungsmodus, der in einer gegebenen Architektur als ein einzelner Adressierungsmodus behandelt wird, eine Funktionalität darstellen, die in einer anderen Architektur von zwei oder mehr Adressierungsmodi abgedeckt wird. Beispielsweise behandeln einige komplexe CISC-Architekturen (CISC = Instruction Set Computer), wie beispielsweise die VAX der Digital Equipment Corporation (DEC), Register und Literal- oder Sofortkonstanten als nur einen weiteren Adressierungsmodus. Andere, wie das IBM System / 360 und seine Nachfolger sowie die am meisten reduzierten RISC-Designs (RISC = Instruction Set Computer), codieren diese Informationen innerhalb des Befehls. Somit haben die letzteren Maschinen drei unterschiedliche Befehlscodes zum Kopieren eines Registers in ein anderes, zum Kopieren einer Literalkonstante in ein Register und zum Kopieren des Inhalts eines Speicherorts in ein Register, während der VAX nur einen einzigen “MOV” -Befehl hat.

Der Begriff “Adressierungsmodus” unterliegt selbst unterschiedlichen Interpretationen: entweder “Speicheradressenberechnungsmodus” oder “Operandenzugriffsmodus”. Bei der ersten Interpretation wird davon ausgegangen, dass Anweisungen, die nicht aus dem Speicher lesen oder in den Speicher schreiben (z. B. “Literal zum Register hinzufügen”), keinen “Adressierungsmodus” haben. Die zweite Interpretation ermöglicht Maschinen wie VAX, die Operandenmodusbits verwenden, um ein Register oder einen Literaloperanden zu ermöglichen. Nur die erste Interpretation gilt für Anweisungen wie “effektive Adresse laden”.

Die unten aufgeführten Adressierungsmodi sind in Codeadressierung und Datenadressierung unterteilt. Die meisten Computerarchitekturen behalten diese Unterscheidung bei, aber es gibt (oder gab) einige Architekturen, mit denen (fast) alle Adressierungsmodi in jedem Kontext verwendet werden können.

Die unten gezeigten Anweisungen sind rein repräsentativ, um die Adressierungsmodi zu veranschaulichen, und spiegeln nicht unbedingt die von einem bestimmten Computer verwendeten Mnemoniken wider.

Anzahl der Adressierungsmodi[edit]

Unterschiedliche Computerarchitekturen unterscheiden sich stark in Bezug auf die Anzahl der Adressierungsmodi, die sie in der Hardware bereitstellen. Das Eliminieren komplexer Adressierungsmodi und die Verwendung nur eines oder einiger einfacherer Adressierungsmodi bietet einige Vorteile, obwohl einige zusätzliche Anweisungen und möglicherweise ein zusätzliches Register erforderlich sind.[1][2] Es hat sich bewährt[3][4][5] Es ist viel einfacher, Pipeline-CPUs zu entwerfen, wenn nur einfache Adressierungsmodi verfügbar sind.

after-content-x4

Die meisten RISC-Architekturen verfügen nur über fünf einfache Adressierungsmodi, während CISC-Architekturen wie die DEC VAX über ein Dutzend Adressierungsmodi verfügen, von denen einige recht kompliziert sind. Die IBM System / 360-Architektur hatte nur drei Adressierungsmodi. Für das System / 390 wurden einige weitere hinzugefügt.

Wenn es nur wenige Adressierungsmodi gibt, wird der bestimmte erforderliche Adressierungsmodus normalerweise im Anweisungscode codiert (z. B. IBM System / 360 und Nachfolger, die meisten RISC). Wenn es jedoch viele Adressierungsmodi gibt, wird in der Anweisung häufig ein bestimmtes Feld zur Angabe des Adressierungsmodus beiseite gelegt. Der DEC VAX erlaubte mehrere Speicheroperanden für fast alle Befehle und reservierte daher die ersten paar Bits jedes Operandenspezifizierers, um den Adressierungsmodus für diesen bestimmten Operanden anzugeben. Wenn die Adressierungsmodus-Spezifiziererbits von den Opcode-Operationsbits getrennt gehalten werden, wird ein orthogonaler Befehlssatz erzeugt.

Selbst auf einem Computer mit vielen Adressierungsmodi können Messungen von tatsächlichen Programmen durchgeführt werden[6] Geben Sie an, dass die unten aufgeführten einfachen Adressierungsmodi mindestens 90% aller verwendeten Adressierungsmodi ausmachen. Da die meisten dieser Messungen auf Code basieren, der von Compilern aus Hochsprachen generiert wurde, spiegelt dies in gewissem Maße die Einschränkungen der verwendeten Compiler wider.[7][6][8]

Nützliche Nebenwirkung[edit]

Einige Befehlssatzarchitekturen wie Intel x86 und IBM / 360 und seine Nachfolger haben eine effektive Adresse laden Anweisung.[9][10] Dies führt eine Berechnung der effektiven Operandenadresse durch, aber anstatt auf diesen Speicherort einzuwirken, lädt es die Adresse, auf die zugegriffen worden wäre, in ein Register. Dies kann nützlich sein, wenn die Adresse eines Array-Elements an eine Unterroutine übergeben wird. Es kann auch eine etwas hinterhältige Methode sein, mehr Berechnungen als normal in einer Anweisung durchzuführen. Wenn Sie beispielsweise einen solchen Befehl mit dem Adressierungsmodus “Basis + Index + Offset” (siehe unten) verwenden, können Sie zwei Register und eine Konstante in einem Befehl addieren.

Einfache Adressierungsmodi für Code[edit]

Absolut oder direkt[edit]

   +----+------------------------------+
   |jump|           address            |
   +----+------------------------------+

   (Effective PC address = address)

Die effektive Adresse für eine absolute Befehlsadresse ist der Adressparameter selbst ohne Änderungen.

PC-relativ[edit]

   +----+------------------------------+
   |jump|           offset             |    jump relative
   +----+------------------------------+

   (Effective PC address = next instruction address + offset, offset may be negative)

Die effektive Adresse für eine PC-relative Befehlsadresse ist der Versatzparameter, der zur Adresse des nächsten Befehls hinzugefügt wird. Dieser Offset wird normalerweise signiert, um sowohl vor als auch nach der Anweisung auf Code verweisen zu können.

Dies ist besonders nützlich in Verbindung mit Sprüngen, da typische Sprünge zu Anweisungen in der Nähe führen (meistens in einer Hochsprache) wenn oder während Aussagen sind ziemlich kurz). Messungen tatsächlicher Programme legen nahe, dass ein 8- oder 10-Bit-Offset groß genug für etwa 90% der bedingten Sprünge ist (ungefähr ± 128 oder ± 512 Bytes).[11]

Ein weiterer Vorteil der PC-relativen Adressierung besteht darin, dass der Code positionsunabhängig sein kann, dh er kann überall im Speicher geladen werden, ohne dass Adressen angepasst werden müssen.

Einige Versionen dieses Adressierungsmodus können bedingt sein und sich auf zwei Register (“Sprung, wenn reg1 = reg2”), ein Register (“Sprung, wenn nicht reg1 = 0”) oder keine Register beziehen, implizit auf ein zuvor gesetztes Bit im Statusregister . Siehe auch bedingte Ausführung unten.

Indirekt registrieren[edit]

   +-------+-----+
   |jumpVia| reg |
   +-------+-----+

   (Effective PC address = contents of register 'reg')

Die effektive Adresse für einen indirekten Registerbefehl ist die Adresse im angegebenen Register. Zum Beispiel (A7), um auf den Inhalt des Adressregisters A7 zuzugreifen.

Der Effekt besteht darin, die Kontrolle an den Befehl zu übertragen, dessen Adresse sich im angegebenen Register befindet.

Viele RISC-Maschinen sowie das CISC IBM System / 360 und seine Nachfolger verfügen über Anweisungen zum Aufrufen von Unterprogrammen, mit denen die Rücksprungadresse in ein Adressregister gestellt wird. Der Register-indirekte Adressierungsmodus wird verwendet, um von diesem Unterprogrammaufruf zurückzukehren.

Sequentielle Adressierungsmodi[edit]

Sequentielle Ausführung[edit]

   +------+
   | nop  |              execute the following instruction
   +------+

   (Effective PC address = next instruction address)

Die CPU führt nach Ausführung eines sequentiellen Befehls sofort den folgenden Befehl aus.

Die sequentielle Ausführung wird auf einigen Computern nicht als Adressierungsmodus angesehen.

Die meisten Anweisungen auf den meisten CPU-Architekturen sind sequentielle Anweisungen. Da es sich bei den meisten Anweisungen um sequentielle Anweisungen handelt, fügen CPU-Entwickler häufig Funktionen hinzu, die die Leistung der anderen Anweisungen – Verzweigungsanweisungen – absichtlich beeinträchtigen, damit diese sequenziellen Anweisungen schneller ausgeführt werden.

Bedingte Verzweigungen laden den PC je nach Bedingung mit einem von zwei möglichen Ergebnissen. Die meisten CPU-Architekturen verwenden einen anderen Adressierungsmodus für den Zweig “genommen” und eine sequentielle Ausführung für den Zweig “nicht genommen”.

Viele Funktionen in modernen CPUs – Befehlsvorabruf und komplexeres Pipelineing, Ausführung außerhalb der Reihenfolge usw. – halten die Illusion aufrecht, dass jeder Befehl beendet wird, bevor der nächste beginnt, und liefern dieselben Endergebnisse, auch wenn dies nicht genau das ist passiert intern.

Jeder “Grundblock” solcher sequentiellen Anweisungen weist sowohl eine zeitliche als auch eine räumliche Referenzlokalität auf.

CPUs, die keine sequentielle Ausführung verwenden[edit]

CPUs, die keine sequentielle Ausführung mit einem Programmzähler verwenden, sind äußerst selten. In einigen CPUs gibt jeder Befehl immer die Adresse des nächsten Befehls an. Solche CPUs haben einen Befehlszeiger, der diese angegebene Adresse enthält; Es handelt sich nicht um einen Programmzähler, da keine Inkrementierung vorgesehen ist. Zu solchen CPUs gehören einige Drum-Memory-Computer wie der IBM 650, der SECD-Computer und der RTX 32P.[12]

Andere Computerarchitekturen gehen viel weiter und versuchen, den von Neumann-Engpass mithilfe verschiedener Alternativen zum Programmzähler zu umgehen.

Bedingte Ausführung[edit]

Einige Computerarchitekturen verfügen über bedingte Anweisungen (z. B. ARM, jedoch nicht mehr für alle Anweisungen im 64-Bit-Modus) oder Anweisungen zum bedingten Laden (z. B. x86), die in einigen Fällen bedingte Verzweigungen unnötig machen und ein Leeren der Anweisungspipeline vermeiden können. Eine Anweisung wie “Vergleichen” wird verwendet, um einen Bedingungscode festzulegen, und nachfolgende Anweisungen enthalten einen Test für diesen Bedingungscode, um festzustellen, ob sie befolgt oder ignoriert werden.

Überspringen[edit]

   +------+-----+-----+
   |skipEQ| reg1| reg2|      skip the next instruction if reg1=reg2
   +------+-----+-----+

   (Effective PC address = next instruction address + 1)

Das Überspringen der Adressierung kann als eine spezielle Art des PC-relativen Adressierungsmodus mit einem festen Versatz von “+1” angesehen werden. Wie bei der PC-relativen Adressierung verfügen einige CPUs über Versionen dieses Adressierungsmodus, die sich nur auf ein Register (“Überspringen, wenn reg1 = 0”) oder auf keine Register beziehen und implizit auf ein zuvor gesetztes Bit im Statusregister verweisen. Andere CPUs haben eine Version, die ein bestimmtes Bit in einem bestimmten zu testenden Byte auswählt (“Überspringen, wenn Bit 7 von reg12 0 ist”).

Im Gegensatz zu allen anderen bedingten Verzweigungen muss ein Befehl “Überspringen” niemals die Befehlspipeline leeren, obwohl möglicherweise der nächste Befehl ignoriert werden muss.

Einfache Adressierungsmodi für Daten[edit]

Registrieren (oder direkt registrieren)[edit]

   +------+-----+-----+-----+
   | mul  | reg1| reg2| reg3|      reg1 := reg2 * reg3;
   +------+-----+-----+-----+

Dieser “Adressierungsmodus” hat keine effektive Adresse und wird auf einigen Computern nicht als Adressierungsmodus angesehen.

In diesem Beispiel befinden sich alle Operanden in Registern, und das Ergebnis wird in ein Register gestellt.

Basis plus Offset und Variationen[edit]

Dies wird manchmal als “Basis plus Verschiebung” bezeichnet.

   +------+-----+-----+----------------+
   | load | reg | base|     offset     |  reg := RAM[base + offset]
   +------+-----+-----+----------------+

   (Effective address = offset + contents of specified base register)

Der Offset ist normalerweise ein vorzeichenbehafteter 16-Bit-Wert (obwohl der 80386 ihn auf 32 Bit erweitert hat).

Wenn der Versatz Null ist, wird dies ein Beispiel für indirekt registrieren Adressierung; Die effektive Adresse ist nur der Wert im Basisregister.

Bei vielen RISC-Maschinen ist das Register 0 auf den Wert Null festgelegt. Wenn Register 0 als Basisregister verwendet wird, wird dies ein Beispiel für absolute Adressierung. Es kann jedoch nur auf einen kleinen Teil des Speichers zugegriffen werden (64 Kilobyte, wenn der Offset 16 Bit beträgt).

Der 16-Bit-Offset scheint im Verhältnis zur Größe der aktuellen Computerspeicher sehr klein zu sein (weshalb der 80386 ihn auf 32-Bit erweitert hat). Es könnte schlimmer sein: IBM System / 360-Mainframes haben nur einen vorzeichenlosen 12-Bit-Offset. Es gilt jedoch das Prinzip der Referenzlokalität: Innerhalb kurzer Zeit sind die meisten Datenelemente, auf die ein Programm zugreifen möchte, ziemlich nahe beieinander.

Dieser Adressierungsmodus ist eng mit dem indizierten absoluten Adressierungsmodus verbunden.

Beispiel 1: Innerhalb eines Unterprogramms interessiert sich ein Programmierer hauptsächlich für die Parameter und die lokalen Variablen, die selten 64 KB überschreiten und für die ein Basisregister (der Rahmenzeiger) ausreicht. Wenn diese Routine eine Klassenmethode in einer objektorientierten Sprache ist, wird ein zweites Basisregister benötigt, das auf die Attribute für das aktuelle Objekt zeigt (diese oder selbst in einigen Hochsprachen).

Beispiel 2: Wenn das Basisregister die Adresse eines zusammengesetzten Typs (eines Datensatzes oder einer Struktur) enthält, kann der Versatz verwendet werden, um ein Feld aus diesem Datensatz auszuwählen (die meisten Datensätze / Strukturen sind kleiner als 32 kB).

Sofort / wörtlich[edit]

   +------+-----+-----+----------------+
   | add  | reg1| reg2|    constant    |    reg1 := reg2 + constant;
   +------+-----+-----+----------------+

Dieser “Adressierungsmodus” hat keine effektive Adresse und wird auf einigen Computern nicht als Adressierungsmodus angesehen.

Die Konstante kann signiert oder nicht signiert sein. Zum Beispiel, move.l #$FEEDABBA, D0 um den unmittelbaren Hex-Wert von “FEEDABBA” in das Register D0 zu verschieben.

Anstatt einen Operanden aus dem Speicher zu verwenden, wird der Wert des Operanden im Befehl selbst gespeichert. Auf der DEC VAX-Maschine können die Literalenoperandengrößen 6, 8, 16 oder 32 Bit lang sein.

Andrew Tanenbaum zeigte, dass 98% aller Konstanten in einem Programm in 13 Bit passen würden (siehe RISC-Designphilosophie).

Implizit[edit]

   +-----------------+
   | clear carry bit |
   +-----------------+

   +-------------------+
   | clear Accumulator |
   +-------------------+

Der implizite Adressierungsmodus, auch impliziter Adressierungsmodus (X86-Assemblersprache) genannt, gibt weder für die Quelle noch für das Ziel (oder manchmal für beide) explizit eine effektive Adresse an.

Entweder die effektive Quelladresse (falls vorhanden) oder die effektive Zieladresse (oder manchmal beides) wird durch den Opcode impliziert.

Die implizite Adressierung war auf älteren Computern (bis Mitte der 1970er Jahre) weit verbreitet. Solche Computer hatten typischerweise nur ein einziges Register, in dem Arithmetik ausgeführt werden konnte – den Akkumulator. Solche Akkumulatormaschinen verweisen implizit in fast jedem Befehl auf diesen Akkumulator. Zum Beispiel die Operation < a := b + c; > kann mit der Sequenz durchgeführt werden < load b; add c; store a; > – Das Ziel (der Akkumulator) ist in jeder Anweisung “Laden” und “Hinzufügen” enthalten. Die Quelle (der Akkumulator) ist in jeder “Speicher” -Anweisung enthalten.

Spätere Computer hatten im Allgemeinen mehr als ein Universalregister oder einen RAM-Speicherort, der die Quelle oder das Ziel oder beides für die Arithmetik sein kann. Daher benötigen spätere Computer einen anderen Adressierungsmodus, um die Quelle und das Ziel der Arithmetik anzugeben.

Unter den x86-Befehlen verwenden einige implizite Register für einen der Operanden oder Ergebnisse (Multiplikation, Division, Zählen des bedingten Sprungs).

Viele Computer (wie x86 und AVR) haben ein spezielles Register, das als Stapelzeiger bezeichnet wird und implizit inkrementiert oder dekrementiert wird, wenn Daten vom Stapel gepusht oder gepoppt werden, und die effektive Quell- oder Zieladresse ist (implizit) die darin gespeicherte Adresse Stapelzeiger.

Viele 32-Bit-Computer (wie 68000, ARM oder PowerPC) verfügen über mehr als ein Register, das als Stapelzeiger verwendet werden kann. Verwenden Sie daher den Adressierungsmodus “Register Autoincrement Indirect”, um anzugeben, welches dieser Register wann verwendet werden soll Daten von einem Stapel verschieben oder abrufen.

Einige aktuelle Computerarchitekturen (z. B. IBM / 390 und Intel Pentium) enthalten einige Anweisungen mit impliziten Operanden, um die Abwärtskompatibilität mit früheren Designs zu gewährleisten.

Auf vielen Computern geben Anweisungen, die das Benutzer- / Systemmodusbit, das Interrupt-Aktivierungsbit usw. umdrehen, implizit das spezielle Register an, das diese Bits enthält. Dies vereinfacht die Hardware, die zum Abfangen dieser Anweisungen erforderlich ist, um die Virtualisierungsanforderungen von Popek und Goldberg zu erfüllen. Auf einem solchen System muss die Trap-Logik keinen Operanden (oder die endgültige effektive Adresse), sondern nur den Opcode anzeigen .

Es wurden einige CPUs entwickelt, bei denen jeder Operand in jedem Befehl implizit angegeben wird – CPUs mit Nulloperanden.

Andere Adressierungsmodi für Code oder Daten[edit]

Absolut / direkt[edit]

   +------+-----+--------------------------------------+
   | load | reg |         address                      |
   +------+-----+--------------------------------------+

   (Effective address = address as given in instruction)

Dies erfordert Platz in einer Anweisung für eine ziemlich große Adresse. Es ist häufig auf CISC-Computern mit Anweisungen variabler Länge verfügbar, z. B. x86.

Einige RISC-Maschinen haben eine spezielle Oberes Literal laden Befehl, der eine 16- oder 20-Bit-Konstante in die obere Hälfte eines Registers setzt. Dies kann dann als Basisregister in einem Adressierungsmodus mit Basis-Plus-Offset verwendet werden, der die niederwertigen 16 oder 12 Bits liefert. Die Kombination ermöglicht eine vollständige 32-Bit-Adresse.

Indiziert absolut[edit]

   +------+-----+-----+--------------------------------+
   | load | reg |index|         address                |
   +------+-----+-----+--------------------------------+

   (Effective address = address + contents of specified index register)

Dies erfordert auch Platz in einer Anweisung für eine ziemlich große Adresse. Die Adresse könnte der Anfang eines Arrays oder Vektors sein, und der Index könnte das bestimmte erforderliche Array-Element auswählen. Der Prozessor kann das Indexregister skalieren, um die Größe jedes Array-Elements zu berücksichtigen.

Beachten Sie, dass dies mehr oder weniger dem Adressierungsmodus mit Basis plus Offset entspricht, mit der Ausnahme, dass der Offset in diesem Fall groß genug ist, um einen beliebigen Speicherort zu adressieren.

Beispiel 1: Innerhalb einer Unterroutine kann ein Programmierer eine Zeichenfolge als lokale Konstante oder statische Variable definieren. Die Adresse der Zeichenfolge wird in der Literaladresse in der Anweisung gespeichert. Der Offset – welches Zeichen der Zeichenfolge für diese Iteration einer Schleife verwendet werden soll – wird im Indexregister gespeichert.

Beispiel 2: Ein Programmierer kann mehrere große Arrays als globale oder als Klassenvariablen definieren. Der Start des Arrays wird in der Literaladresse (möglicherweise beim Laden des Programms durch einen verschiebenden Loader geändert) der Anweisung gespeichert, die darauf verweist. Der Offset – welches Element aus dem Array für diese Iteration einer Schleife verwendet werden soll – wird im Indexregister gespeichert. Oft verwenden die Anweisungen in einer Schleife dasselbe Register für den Schleifenzähler und die Offsets mehrerer Arrays erneut.

Basis plus Index[edit]

   +------+-----+-----+-----+
   | load | reg | base|index|
   +------+-----+-----+-----+

   (Effective address = contents of specified base register + contents of specified index register)

Das Basisregister könnte die Startadresse eines Arrays oder Vektors enthalten, und der Index könnte das bestimmte erforderliche Array-Element auswählen. Der Prozessor kann das Indexregister skalieren, um die Größe jedes Array-Elements zu berücksichtigen. Dies kann für den Zugriff auf Elemente eines als Parameter übergebenen Arrays verwendet werden.

Basis plus Index plus Offset[edit]

   +------+-----+-----+-----+----------------+
   | load | reg | base|index|         offset |
   +------+-----+-----+-----+----------------+

   (Effective address = offset + contents of specified base register + contents of specified index register)

Das Basisregister könnte die Startadresse eines Arrays oder eines Vektors von Datensätzen enthalten, der Index könnte den bestimmten erforderlichen Datensatz auswählen und der Versatz könnte ein Feld innerhalb dieses Datensatzes auswählen. Der Prozessor kann das Indexregister skalieren, um die Größe jedes Array-Elements zu berücksichtigen.

Skaliert[edit]

   +------+-----+-----+-----+
   | load | reg | base|index|
   +------+-----+-----+-----+

   (Effective address = contents of specified base register + scaled contents of specified index register)

Das Basisregister könnte die Startadresse eines Arrays oder einer Vektordatenstruktur enthalten, und der Index könnte den Versatz des einen bestimmten erforderlichen Array-Elements enthalten.

Dieser Adressierungsmodus skaliert den Wert im Indexregister dynamisch, um die Größe jedes Array-Elements zu berücksichtigen. Wenn es sich bei den Array-Elementen beispielsweise um Gleitkommazahlen mit doppelter Genauigkeit handelt, die jeweils 8 Byte belegen, wird der Wert im Indexregister vor dem Multiplizieren mit 8 multipliziert wird bei der effektiven Adressberechnung verwendet. Der Skalierungsfaktor ist normalerweise auf eine Zweierpotenz beschränkt, so dass eine Verschiebung anstelle einer Multiplikation verwendet werden kann.

Indirekt registrieren[edit]

   +------+------+-----+
   | load | reg1 | base|
   +------+------+-----+
 
   (Effective address = contents of base register)

Einige Computer haben dies als eindeutigen Adressierungsmodus. Viele Computer verwenden nur Basis plus Offset mit einem Versatzwert von 0. Zum Beispiel (A7)

Registrieren Sie die automatische Inkrementierung indirekt[edit]

   +------+-----+-------+
   | load | reg | base  |
   +------+-----+-------+

   (Effective address = contents of base register)

Nach dem Bestimmen der effektiven Adresse wird der Wert im Basisregister um die Größe des Datenelements erhöht, auf das zugegriffen werden soll. Zum Beispiel würde (A7) + auf den Inhalt des Adressregisters A7 zugreifen und dann den Adresszeiger von A7 um 1 erhöhen (normalerweise 1 Wort). Innerhalb einer Schleife kann dieser Adressierungsmodus verwendet werden, um alle Elemente eines Arrays oder Vektors zu durchlaufen.

In Hochsprachen wird oft angenommen, dass Funktionen, die ein Ergebnis zurückgeben, keine Nebenwirkungen haben sollten (fehlende Nebenwirkungen erleichtern das Verständnis und die Validierung des Programms erheblich). Dieser Adressierungsmodus hat den Nebeneffekt, dass das Basisregister geändert wird. Wenn der nachfolgende Speicherzugriff einen Fehler verursacht (z. B. Seitenfehler, Busfehler, Adressfehler), der zu einem Interrupt führt, wird das Neustarten des Befehls viel problematischer, da ein oder mehrere Register möglicherweise auf den Zustand zurückgesetzt werden müssen, in dem sie sich zuvor befanden Die Anweisung wurde ursprünglich gestartet.

Es gab mindestens zwei Computerarchitekturen, bei denen Implementierungsprobleme hinsichtlich der Wiederherstellung nach Interrupts aufgetreten sind, wenn dieser Adressierungsmodus verwendet wird:

  • Motorola 68000 (Adresse wird in 24 Bit dargestellt). Könnte ein oder zwei Autoincrement-Registeroperanden haben. Der 68010+ löste das Problem, indem er den internen Status des Prozessors bei Bus- oder Adressfehlern speicherte.
  • DEC VAX. Kann bis zu 6 Autoincrement-Registeroperanden haben. Jeder Operandenzugriff kann zwei Seitenfehler verursachen (wenn Operanden zufällig eine Seitengrenze überspannen). Natürlich kann der Befehl selbst über 50 Byte lang sein und sich auch über eine Seitengrenze erstrecken!

Registrieren Sie die automatische Dekrementierung indirekt[edit]

   +------+-----+-----+
   | load | reg | base|
   +------+-----+-----+

   (Effective address = new contents of base register)

Vor dem Bestimmen der effektiven Adresse wird der Wert im Basisregister um die Größe des Datenelements dekrementiert, auf das zugegriffen werden soll.

Innerhalb einer Schleife kann dieser Adressierungsmodus verwendet werden, um alle Elemente eines Arrays oder Vektors rückwärts zu durchlaufen. Ein Stapel kann implementiert werden, indem dieser Modus in Verbindung mit dem vorherigen Adressierungsmodus (automatische Inkrementierung) verwendet wird.

Siehe die Diskussion der Nebenwirkungen im Adressierungsmodus für die automatische Inkrementierung.

Speicher indirekt[edit]

Jeder der in diesem Artikel erwähnten Adressierungsmodi kann ein zusätzliches Bit enthalten, um die indirekte Adressierung anzuzeigen, dh die unter Verwendung eines bestimmten Modus berechnete Adresse ist tatsächlich die Adresse eines Ortes (normalerweise ein vollständiges Wort), der die tatsächliche effektive Adresse enthält.

Die indirekte Adressierung kann für Code oder Daten verwendet werden. Es kann die Umsetzung von machen Zeiger, Verweise, oder Griffe viel einfacher und kann es auch einfacher machen, Unterprogramme aufzurufen, die ansonsten nicht adressierbar sind. Die indirekte Adressierung führt aufgrund des zusätzlichen Speicherzugriffs zu Leistungseinbußen.

Einige frühe Minicomputer (z. B. DEC PDP-8, Data General Nova) hatten nur wenige Register und nur einen begrenzten Adressierungsbereich (8 Bit). Daher war die Verwendung der indirekten Speicheradressierung fast die einzige Möglichkeit, sich auf eine signifikante Speichermenge zu beziehen.

PC-relativ[edit]

   +------+------+---------+----------------+
   | load | reg1 | base=PC |     offset     |
   +------+------+---------+----------------+

   reg1 := RAM[PC + offset]
   (Effective address = PC + offset)

Der PC-relative Adressierungsmodus kann verwendet werden, um ein Register mit einem Wert zu laden, der im Programmspeicher in kurzer Entfernung vom aktuellen Befehl gespeichert ist. Dies kann als Sonderfall des Adressierungsmodus “Basis plus Offset” angesehen werden, bei dem der Programmzähler (PC) als “Basisregister” ausgewählt wird.

Es gibt einige CPUs, die PC-bezogene Datenreferenzen unterstützen. Solche CPUs umfassen:

Der MOS 6502 und seine Ableitungen verwendeten die relative Adressierung für alle Verzweigungsbefehle. Nur diese Anweisungen verwendeten diesen Modus, Sprünge verwendeten eine Vielzahl anderer Adressierungsmodi.

Die x86-64-Architektur und die 64-Bit-ARMv8-A-Architektur[13] haben PC-relative Adressierungsmodi, die in x86-64 als “RIP-relativ” und in ARMv8-A als “literal” bezeichnet werden. Das Motorola 6809 unterstützt auch einen PC-relativen Adressierungsmodus.

Die PDP-11-Architektur, die VAX-Architektur und die 32-Bit-ARM-Architektur unterstützen die PC-relative Adressierung, indem der PC in der Registerdatei enthalten ist.

Wenn dieser Adressierungsmodus verwendet wird, platziert der Compiler die Konstanten normalerweise unmittelbar vor oder unmittelbar nach der Subroutine, die sie verwendet, in einem Literalpool, um zu verhindern, dass diese Konstanten versehentlich als Anweisungen ausgeführt werden.

Dieser Adressierungsmodus, der immer Daten aus dem Speicher abruft oder Daten im Speicher speichert und dann nacheinander durchfällt, um den nächsten Befehl auszuführen (die effektive Adresse zeigt auf Daten), sollte nicht mit “PC-relativer Zweig” verwechselt werden, der keine Daten abruft von oder speichern Sie Daten im Speicher, sondern verzweigen stattdessen zu einem anderen Befehl mit dem angegebenen Versatz (die effektive Adresse zeigt auf einen ausführbaren Befehl).

Veraltete Adressierungsmodi[edit]

Die hier aufgeführten Adressierungsmodi wurden in der Zeit von 1950 bis 1980 verwendet, sind jedoch auf den meisten aktuellen Computern nicht mehr verfügbar. Diese Liste ist keineswegs vollständig; Von Zeit zu Zeit wurden viele andere interessante und eigenartige Adressierungsmodi verwendet, z. B. das Absolut-Minus-Logische ODER von zwei oder drei Indexregistern.[14][15]

Mehrstufiger Speicher indirekt[edit]

Wenn die Wortgröße größer als die Adresse ist, kann für das Wort, auf das für die speicherindirekte Adressierung verwiesen wird, selbst ein indirektes Flag gesetzt werden, um einen anderen indirekten Speicherzyklus anzuzeigen. Dieses Flag wird als bezeichnet Indirektionsbitund der resultierende Zeiger ist ein markierter Zeiger, wobei das Indirektionsbit markiert, ob es ein direkter Zeiger oder ein indirekter Zeiger ist. Es ist darauf zu achten, dass sich eine Kette indirekter Adressen nicht auf sich selbst bezieht. Wenn dies der Fall ist, kann beim Versuch, eine Adresse aufzulösen, eine Endlosschleife auftreten.

Der IBM 1620, der Data General Nova, die HP 2100-Serie und der NAR 2 verfügen jeweils über einen solchen indirekten mehrstufigen Speicher und könnten in eine solche unendliche Adressberechnungsschleife eintreten. Der Speicher-indirekte Adressierungsmodus auf dem Nova beeinflusste die Erfindung des indirekten Thread-Codes.

Der DEC PDP-10-Computer mit 18-Bit-Adressen und 36-Bit-Wörtern ermöglichte eine mehrstufige indirekte Adressierung mit der Möglichkeit, in jeder Stufe auch ein Indexregister zu verwenden.

Speicherabgebildete Register[edit]

Auf einigen Computern wurde angenommen, dass die Register die ersten 8 oder 16 Wörter des Speichers belegen (z. B. ICL 1900, DEC PDP-10). Dies bedeutete, dass kein separater Befehl “Register zum Registrieren hinzufügen” erforderlich war – man konnte einfach den Befehl “Speicher zum Registrieren hinzufügen” verwenden.

Bei frühen Modellen des PDP-10, die keinen Cache-Speicher hatten, lief eine enge innere Schleife, die in die ersten paar Wörter des Speichers geladen wurde (wo die schnellen Register bei Installation adressierbar waren), viel schneller als in Magnetkernspeicher.

Spätere Modelle der DEC PDP-11-Serie haben die Register auf Adressen im Eingabe- / Ausgabebereich abgebildet, dies sollte jedoch in erster Linie eine Ferndiagnose ermöglichen. Verwirrenderweise wurden die 16-Bit-Register auf aufeinanderfolgende 8-Bit-Byteadressen abgebildet.

Speicher indirekt und automatisch erhöht[edit]

Der DEC PDP-8-Minicomputer hatte acht spezielle Standorte (an den Adressen 8 bis 15). Beim Zugriff über die indirekte Speicheradressierung werden diese Speicherorte nach der Verwendung automatisch erhöht.[16] Dies machte es einfach, den Speicher in einer Schleife zu durchlaufen, ohne dass Register verwendet werden mussten, um die Schritte zu handhaben.

Der Data General Nova-Minicomputer hatte 16 spezielle Speicherplätze an den Adressen 16 bis 31.[17] Beim Zugriff über die indirekte Speicheradressierung werden 16 bis 23 vor der Verwendung automatisch erhöht, und 24 bis 31 werden vor der Verwendung automatisch verringert.

Nullseite[edit]

Die Prozessoren Data General Nova, Motorola 6800 und MOS Technology 6502 hatten nur sehr wenige interne Register. Arithmetische und logische Anweisungen wurden hauptsächlich für Werte im Speicher im Gegensatz zu internen Registern ausgeführt. Infolgedessen erforderten viele Befehle einen Zwei-Byte-Speicherort (16 Bit) im Speicher. Da Opcodes auf diesen Prozessoren nur ein Byte (8 Bit) lang waren, könnten Speicheradressen einen wesentlichen Teil der Codegröße ausmachen.

Die Entwickler dieser Prozessoren enthielten eine teilweise Abhilfe, die als “Nullseiten” -Adressierung bekannt ist. Auf die anfänglichen 256 Bytes Speicher ($ 0000 – $ 00FF; auch bekannt als Seite “0”) kann mit einer absoluten oder indizierten 1-Byte-Speicheradresse zugegriffen werden. Dies reduzierte die Befehlsausführungszeit um einen Taktzyklus und die Befehlslänge um ein Byte. Durch das Speichern häufig verwendeter Daten in dieser Region könnten Programme kleiner und schneller gemacht werden.

Infolgedessen wurde die Nullseite ähnlich wie eine Registerdatei verwendet. Auf vielen Systemen führte dies jedoch zu einer hohen Auslastung des Nullseiten-Speicherbereichs durch das Betriebssystem und Benutzerprogramme, was seine Verwendung einschränkte, da der freie Speicherplatz begrenzt war.

Direkte Seite[edit]

Der Nullseitenadressmodus wurde in mehreren späten 8-Bit-Prozessoren des Modells verbessert, darunter der WDC 65816, der CSG 65CE02 und das Motorola 6809. Der neue Modus, der als “direkte Seitenadressierung” bezeichnet wird, bietet die Möglichkeit, die 256- zu verschieben. Byte-Null-Seiten-Speicherfenster vom Speicheranfang (Offset-Adresse $ 0000) bis zu einem neuen Speicherort innerhalb der ersten 64 KB Speicher.

Mit dem CSG 65CE02 konnte die direkte Seite an eine beliebige 256-Byte-Grenze innerhalb der ersten 64 KB Speicher verschoben werden, indem ein 8-Bit-Versatzwert im neuen Basisseitenregister (B) gespeichert wurde. Das Motorola 6809 könnte dasselbe mit seinem DP-Register (Direct Page) tun. Das WDC 65816 ging noch einen Schritt weiter und ermöglichte das Verschieben der Direktseite an eine beliebige Stelle innerhalb der ersten 64 KB Speicher, indem ein 16-Bit-Offsetwert im neuen Direktregister (D) gespeichert wurde.

Infolgedessen konnte eine größere Anzahl von Programmen den erweiterten direkten Seitenadressierungsmodus im Vergleich zu älteren Prozessoren verwenden, die nur den Nullseitenadressierungsmodus enthielten.

Skalierter Index mit Überprüfung der Grenzen[edit]

Dies ähnelt der skalierten Indexadressierung, außer dass der Befehl zwei zusätzliche Operanden (normalerweise Konstanten) enthält und die Hardware prüft, ob der Indexwert zwischen diesen Grenzen liegt.

Eine andere Variante verwendet Vektordeskriptoren, um die Grenzen zu halten. Dies macht es einfach, dynamisch zugewiesene Arrays zu implementieren und dennoch die vollständigen Grenzen zu überprüfen.

Indirekt zum Bitfeld innerhalb des Wortes[edit]

Einige Computer hatten spezielle indirekte Adressierungsmodi für Unterfelder innerhalb von Wörtern.

Das Zeichen der GE / Honeywell 600-Serie, das ein indirektes Wort adressiert, spezifizierte entweder 6-Bit- oder 9-Bit-Zeichenfelder innerhalb seines 36-Bit-Wortes.

Der ebenfalls 36-Bit-DEC-PDP-10 verfügte über spezielle Anweisungen, mit denen der Speicher als Folge von Bitfeldern fester Größe oder Bytes beliebiger Größe von 1 Bit bis 36 Bit behandelt werden konnte. Ein Ein-Wort-Sequenzdeskriptor im Speicher, der als “Bytezeiger” bezeichnet wird, enthielt die aktuelle Wortadresse innerhalb der Sequenz, eine Bitposition innerhalb eines Wortes und die Größe jedes Bytes.

Es gab Anweisungen zum Laden und Speichern von Bytes über diesen Deskriptor und zum Inkrementieren des Deskriptors, um auf das nächste Byte zu zeigen (Bytes wurden nicht über Wortgrenzen hinweg aufgeteilt). Viele DEC-Programme verwendeten fünf 7-Bit-Bytes pro Wort (einfache ASCII-Zeichen), wobei ein Bit pro Wort nicht verwendet wurde. Implementierungen von C mussten vier 9-Bit-Bytes pro Wort verwenden, da die ‘malloc’-Funktion in C davon ausgeht, dass die Größe von a int ist ein Vielfaches der Größe von a verkohlen;;[18] Das tatsächliche Vielfache wird durch die systemabhängige Operatorgröße für die Kompilierungszeit bestimmt.

Index nächste Anweisung[edit]

Der Elliott 503,[19] der Elliott 803,[19][20] und der Apollo Guidance Computer verwendete nur die absolute Adressierung und hatte keine Indexregister. Daher wurden indirekte Sprünge oder Sprünge durch Register im Befehlssatz nicht unterstützt. Stattdessen könnte es angewiesen werden Fügen Sie den Inhalt des aktuellen Speicherworts zur nächsten Anweisung hinzu. Das Hinzufügen eines kleinen Werts zur nächsten auszuführenden Anweisung kann beispielsweise a ändern JUMP 0 in ein JUMP 20Dadurch wird der Effekt eines indizierten Sprungs erzeugt. Beachten Sie, dass die Anweisung im laufenden Betrieb geändert wird und im Speicher unverändert bleibt, dh es handelt sich nicht um selbstmodifizierenden Code. Wenn der Wert, der zur nächsten Anweisung hinzugefügt wird, groß genug ist, kann der Opcode dieser Anweisung sowie oder anstelle der Adresse geändert werden.

Glossar[edit]

Indirekt
Daten, auf die durch einen Zeiger oder eine Adresse verwiesen wird.
Sofortig
Daten, die direkt in eine Anweisungs- oder Befehlsliste eingebettet sind.
Index
Ein dynamischer Offset, der normalerweise in einem Indexregister gespeichert ist und möglicherweise durch eine Objektgröße skaliert wird.
Offset
Ein sofortiger Mehrwert für eine Adresse; zB entsprechend dem Strukturfeldzugriff in der Programmiersprache C.
Relativ
Eine Adresse, die relativ zu einer anderen Adresse gebildet wird.
Post-Inkrement
Das Schritt einer Adresse nach verwendeten Daten, ähnlich wie *p++ in der Programmiersprache C, die für Stack-Pop-Operationen verwendet wird.
Vorabnahme
Das Dekrementieren einer Adresse vor der Verwendung, ähnlich wie *--p in der Programmiersprache C, die für Stack-Push-Operationen verwendet wird.

Siehe auch[edit]

Verweise[edit]

  1. ^ F. Chow; S. Correll; M. Himelstein; E. Killian; L. Weber (1987). “Wie viele Adressierungsmodi sind genug?”.
  2. ^ John L. Hennessy; Mark A. Horowitz (1986). “Ein Überblick über das MIPS-X-MP-Projekt” (PDF). … MIPS-X verwendet einen einzelnen Adressierungsmodus: Basisregister plus Offset. Dieser einfache Adressierungsmodus ermöglicht es, die Berechnung der effektiven Adresse sehr früh zu beginnen …
  3. ^ Dr. Jon Squire. “Vorlesung 19, Pipelining-Datenweiterleitung”. CS411 Ausgewählte Vorlesungsunterlagen.
  4. ^ “High Performance Computing, Notizen der Klasse 11 (15. und 20. September 2000) – Pipelining”. Archiviert von das Original am 27.12.2013. Abgerufen 08.02.2014.
  5. ^ John Paul Shen, Mikko H. Lipasti (2004). Modernes Prozessordesign. McGraw-Hill Professional. ISBN 9780070570641.
  6. ^ ein b John L. Hennessy; David A. Patterson (2002-05-29). Computerarchitektur: Ein quantitativer Ansatz. p. 104. ISBN 9780080502526. Der C54x verfügt über 17 Datenadressierungsmodi, wobei der Registerzugriff nicht berücksichtigt wird. Die vier in MIPS gefundenen Modi machen jedoch 70% der Modi aus. Autoincrement und Autodecrement, die in einigen RISC-Architekturen zu finden sind, machen weitere 25% der Nutzung aus. Diese Daten wurden aus einer Messung statischer Anweisungen für die C-aufrufbare Bibliothek von 54 DSP-Routinen gesammelt, die in Assemblersprache codiert sind.
  7. ^ Dr. Sofiène Tahar. “Befehlssatzprinzipien: Adressierungsmodusverwendung (Zusammenfassung)” (PDF). Archiviert von das Original (PDF) am 30.09.2011. 3 Programme gemessen an der Maschine mit allen Adressmodi (VAX) … 75% Verschiebung und sofort
  8. ^ Ali-Reza Adl-Tabatabai; Geoff Langdale; Steven Lucco; Robert Wahbe (1995). “Effiziente und sprachunabhängige mobile Programme”. 79% aller ausgeführten Befehle könnten durch RISC-Befehle ersetzt oder unter Verwendung nur einer einfachen Blockbefehlskombination zu RISC-Befehlen synthetisiert werden.
  9. ^ Funktionsprinzipien von IBM System / 360 (PDF). IBM. September 1968. p. 135. A22-6821-7. Abgerufen 12. Juli 2019.
  10. ^ z / Funktionsprinzipien der Architektur (PDF). IBM. September 2017. S. 7–266. SA22-7832-11. Abgerufen 12. Juli 2019.
  11. ^ Kong, Shing; Patterson, David (1995). “Befehlssatzdesign”. Folie 27.
  12. ^ Koopman, Philip (1989). “Architektur des RTX 32P”. Computer stapeln.
  13. ^ “Einführung in die 64-Bit-Architektur von ARMv8”. UIC Academy. quequero.org. 9. April 2014.
  14. ^ 704 Bedienungsanleitung der elektronischen Datenverarbeitungsmaschine (PDF). IBM. 1955. S. 10–11.
  15. ^ Referenzhandbuch IBM 7090 Datenverarbeitungssystem (PDF). IBM. 1962. S. 9–10.
  16. ^ Jones, Douglas, Referenzanweisungen für den PDP-8abgerufen 1. Juli 2013
  17. ^ Freund, Carl, Daten Allgemeiner NOVA-Befehlssatz – Zusammenfassungabgerufen 1. Juli 2013
  18. ^ “C Referenz: Funktion malloc ()”
  19. ^ ein b Dave Brooks. “Einige alte Computer”.
  20. ^ Bill Purvis. “Einige Details der Elliott 803B-Hardware”

Externe Links[edit]


after-content-x4