| Inhaltsverzeichnis
|  | Übersicht Kapitel 3
3.1 Datentypen und Datenformat |  | 3.3 Adressierungsarten

## 3.2 Befehlssätze

- 3.2.1 Begriffe und Definitionen
- 3.2.2 Realisierung eines Befehlssatzes auf Maschinensprache-Ebene
- 3.2.3 Darstellung der verschiedenen Befehlsgruppen

Der Vollständigkeit halber beginnen wir diesen Abschnitt mit der kurzen Zusammenfassung einiger Gesichtspunkte, die bereits in früheren Abschnitten angesprochen wurden.
Ein Programm besteht aus einer Folge von Befehlen, die sequentiell im Speicher abgelegt sind und sich aus einem Befehlscode (Operationscode, OpCode) und den Operanden (Daten) bzw. Zeigern darauf zusammensetzen. Die Operanden liegen ebenfalls im Speicher oder in den Registern des Prozessors bzw. der Ein-/Ausgabe-Schnittstellen vor. Die Menge der von einem Prozessor zur Verfügung gestellten (Maschinen-)Befehle nennt man seinen Befehlssatz (Instruction Set). Die Adressierung des augenblicklich auszuführenden Befehls geschieht durch den Programmzähler (PC), die der Operanden durch den Adreßpuffer (AP). Das Adreßwerk (AU) berechnet nach verschiedenen, im Befehl spezifizierten Verfahren, die Sie im nächsten Abschnitt als Adressierungsarten des Prozessors kennenlernen werden, aus dem Inhalt der Prozessorregister und/oder der im Befehl angegebenen Adresse bzw. einer Distanz zu einer Adresse (Offset) die logische Adresse des Operanden. Diese wird gegebenenfalls noch durch eine Speicherverwaltungs-Einheit (Memory Management Unit MMU) in eine physikalische Adresse umgewandelt. Hier nehmen wir der Einfachheit halber an, daß logische und physikalische Adresse übereinstimmen.)
Das Einlesen eines Befehls in den Prozessor ist im Bild 3.2-1 - stark vereinfachend - skizziert. Dabei wird davon ausgegangen, daß OpCode und Operand bzw. Offset nicht in ein einziges Speicherwort passen. Daher muß zum Lesen des gesamten Befehls zweimal auf den Speicher zugegriffen werden; der Programmzähler muß also zwischendurch (um 1) erhöht werden. Diese Abarbeitung eines Lesezugriffs auf einen Befehl ist bei Mikrocontrollern und einfachen universellen Prozessoren weit verbreitet. RISC-Prozessoren und DSPs besitzen hingegen meist genügend breite Befehlswörter (meist 32 bit, aber auch 40 bis 64 bit), um darin sowohl den OpCode wie auch den/die Operanden bzw. Offsets unterzubringen. In diesem Fall muß nur ein einziges Mal auf den Speicher zugegriffen werden, um einen gesamten Befehl einzulesen. Ein im Befehl direkt angegebener Operand wird im Datenbuspuffer abgelegt und von dort zu der im Befehl spezifizierten Prozessorkomponente weitergereicht. Im Befehl angegebene absolute Adressen werden im Adreßpuffer eingetragen und selektieren von dort den benötigten Operanden. Ein im Befehl angegebener Offset wird vom Adreßwerk zur Berechnung der Operandenadresse herangezogen.

Bild 3.2-1: Lesen eines Befehls aus dem Speicher

Die sequentielle Abarbeitung der Programmbefehle kann durch einen Sprung, durch einen Verzweigungsbefehl, eine Unterbrechungsroutine (vgl. Abschnitt 2.3) oder durch den Aufruf eines Unterprogrammes durchbrochen werden.
Im Bild 3.2-2 ist einerseits die Änderung des sequentiellen Programmflusses durch einen absoluten Sprung (JUMP) angedeutet, bei dem die absolute Zieladresse im Befehl angegeben wird. Sie wird vom Adreßwerk (ohne Weiterbearbeitung) in den Programmzähler geladen. Der nächste Befehl (z.B. ein Ladebefehl LOAD) wird dann von der Zieladresse geladen. Andererseits ist gezeigt, wie der Prozessor auf einen Verzweigungsbefehl (BEQ- Branch Equal) reagiert. Dabei fragt er z.B. den Inhalt eines Registers ab und führt nur dann einen "Sprung"12 aus, wenn dieser gleich 0 ist. Die Zieladresse wird durch das Adreßwerk aus dem im Befehl angegebenen Offset - relativ zum aktuellen Programmzähler-Stand - berechnet. Gewöhnlich enthält dabei der Programmzähler bereits die Adresse des im Speicher unmittelbar auf den Verzweigungsbefehl folgenden Befehls. Das Ergebnis der Adreßberechnung wird als Zieladresse im Programmzähler abgelegt und selektiert wiederum den nächsten auszuführenden Befehl.

Bild 3.2-2: Abarbeitung eines im Speicher liegenden Programms

### 3.2.1 Begriffe und Definitionen |

Zunächst wollen wir einige Begriffe und Definitionen zum Thema Befehlssätze behandeln.

- Ein Befehlssatz heißt orthogonal, wenn jeder Befehl jede Adressierungsart zuläßt.
- Er heißt symmetrisch, wenn alle für einen Befehl relevanten Datentypen, Datenformate und Adressierungsarten sowohl für seine Quell- als auch für seine Zieloperanden zulässig sind. Dies gilt dann insbesondere für die Lade- und Speicherbefehle.

Grundsätzlich unterscheidet man zwischen monadischen Operationen (unäre Operationen) der Form
A := op B
und dyadischen Operationen (binäre Operationen) der Form
A := C op B,
worin B, C Operanden (Konstanten oder Variablen) sind und A eine Variable ist. 'op' steht für eine Operation, die mit diesen Operanden ausgeführt werden kann. Den Variablen werden im Speicher feste Speicherzellen zugewiesen. Vom Maschinenbefehl werden sie durch ihre Adressen angesprochen. Die Operationen werden durch bestimmte binäre Muster selektiert, die im Befehlsregister gespeichert und vom Steuerwerk des Prozessors interpretiert werden.

- Stehen in der dyadischen Operation die Buchstaben A, B, C für paarweise verschiedene Variablen, so spricht man vom Dreiadreß-Format.
- Der Ausdruck
  A := A op B,
  bei dem die Ergebnisvariable A mit einer Eingabevariablen übereinstimmt, wird als Zweiadreß-Format bezeichnet. Man spricht auch von verdeckter Adressierung, da eine Variable sowohl als Eingangsvariable als auch zur Aufnahme des Ergebnisses benutzt wird. Dabei ist es vom Prozessortyp abhängig, ob der erste Operand (wie im obigen Ausdruck) oder der zweite Operand das Ergebnis der Operation aufnimmt.
- Ist die Ergebnisvariable A jedoch stets im Accumulator AC gespeichert, so muß sie nicht explizit adressiert werden. Dies führt zu
  AC := AC op B,
  was als Einadreß-Format bezeichnet wird (implizite Adressierung). Bei den 8-bit-Mikroprozessoren war dieses Befehlsformat der Standard, 16-, 32- und 64-bit-Prozessoren unterstützen jedoch in der Regel das Zweiadreß-Format, z.T. auch das Dreiadreß-Format. Beim Dreiadreß-Format werden dabei die Operanden meistens in den internen Prozessorregistern erwartet.

In der Maschinensprache sowie der Assemblersprache eines Prozessors werden die Befehle in der Regel in der Form angegeben, daß zunächst die Operationen und danach die Operanden hingeschrieben werden:

Maschinensprache: | <OpCode> | {<Operand1>{,<Operand2>}}
Assembler: | <MnemoCode> | {<Operand1>{,<Operand2>}}

- <OpCode> steht darin für das binäre Muster, das die gewünschte Operation im Steuerwerk anspricht. Dieses wird meistens in hexadezimaler Form angegeben. Darin codiert ist u.a. die Anzahl der Wörter, die zu dem Befehl gehören, also insbesondere auch die Anzahl der benötigten Operanden. (Näheres hierzu folgt im Abschnitt 3.2.2.)
- <MnemoCode> bezeichnet eine symbolische Abkürzung für den Befehl, die als sprachliche Gedächtnisstütze für den Menschen leichter zu erlernen und zu merken ist. Die Mnemocodes werden vom Assembler in den OpCode übersetzt, der vom Steuerwerk des Prozessors verstanden wird. So kann z.B. der Befehl:
  "Addiere zum Inhalt des Akkumulators A unter Berücksichtigung des Carry Flags"
  durch die mnemotechnische Abkürzung ADCA (Add with Carry A) repräsentiert werden und vom Assembler in den (hexadezimalen) OpCode '$6D' übersetzt werden.
- Die geschweiften Klammern '{ }' bedeuten, daß der so geklammerte Ausdruck entfallen kann. Dadurch wird der Tatsache Rechnung getragen, daß ein Befehl keinen, einen oder mehrere Operanden haben kann.
- <Operand> steht hier für die Operanden, mit denen die gewünschte Operation durchgeführt werden soll. Wie bereits oben erwähnt, können diese im Befehl als Konstante oder aber durch ihre Speicheradresse bzw. durch eine Distanz (Offset, Displacement) zwischen ihrer Speicheradresse und einem Registerinhalt angegeben werden. Es gibt - wie bereits gesagt - zwei Möglichkeiten dafür, wie eine Adresse im Maschinen-Befehl angegeben wird:
  - <OpCode> <L-Adresse> <H-Adresse>... ,Little-Endian Format,
  - <OpCode> <H-Adresse> <L-Adresse>... ,Big-Endian Format.
  ('H' steht, wie immer, für high höherwertig, 'L' für low niederwertig.) Ist eine Adresse länger als ein Speicherwort, d.h. besitzt der Adreßbus mehr Bits als der Datenbus, so muß der Prozessor mehrfach auf den Speicher zugreifen, um eine vollständige Adresse aus dem Speicher zu lesen.
- <Offset>: Der in einem Befehl zur Adreßberechnung angegebene Offset wird meistens im Zweierkomplement angegeben. Bei einer Breite von k bit liegt er somit im (unsymmetrischen) Bereich
  -2k-1 <= Offset <= 2k-1-1 .
  Ist k ein Vielfaches von 4, so erhält man in hexadezimaler Darstellung
  $80...0 <= Offset <= $7F...F ,
  wobei in jeder der Zahlen die Punkte '...' für (k/4-3) Hexadezimalziffern '0' bzw. 'F' stehen. Als vorzeichenlose Zahl aufgefaßt, liegt er im Bereich:
  0 <= Offset <= 2k-1 .

### 3.2.2 Realisierung eines Befehlssatzes auf Maschinensprache-Ebene |

Im Bild 3.2-3 ist der Aufbau eines Maschinenbefehls skizziert. Bei modernen CISC-Prozessoren ist der OpCode zwischen 1 und 6 byte lang, für jeden Operanden bzw. seine Adresse werden jeweils bis zu 8 byte benötigt. Beim Motorola 68040 z.B. können Maschinenbefehle bis zu 22 byte lang sein. RISC-Prozessoren haben meist eine feste, einheitliche Befehlslänge (von z.B. 32 bit).

Bild 3.2-3: Allgemeiner Aufbau eines Maschinenbefehls

3.2.2.1 Allgemeiner Aufbau eines Maschinenbefehls

Jede Anweisung zur Ausführung einer Operation muß für die Interpretation durch das Steuerwerk des Mikroprozessors in eine Bitkette codiert werden, den OpCode. Aus dem, was wir im Abschnitt 2.6 über die verschiedenen Registertypen gesagt haben, und der Gruppeneinteilung der Befehle im folgenden Unterabschnitt 3.2.3 ergibt sich das allgemeine Format eines OpCodes, wie es im Bild 3.2-4 skizziert ist. Durch dieses Format können alle Operationen dargestellt werden.
Der OpCode ist in einzelne Bitfelder unterteilt, die verschiedene Informationen in binär codierter Form enthalten.

- Das erste Feld, das wir Operationswort nennen, spezifiziert die Befehlsgruppe und die Nummer eines Befehls in seiner Gruppe. Darüber hinaus wird angegeben, wie lang die Operanden sind, auf die der Befehl wirken soll, also ob es sich um Bytes, Wörter, Doppelwörter oder Quadwords handelt. In einem weiteren Bit kann die Richtung eines Datentransports (Lesen aus dem Speicher/Schreiben in den Speicher) vorgegeben werden.
- Die Operanden-Felder geben für jeden Operanden zunächst die gewünschte Adressierungsart an. Dazu gehört insbesondere die Information, ob ein Basisregister oder Indexregister benötigt wird und ob die Adressierung direkt oder indirekt erfolgt. Durch weitere Bits wird festgelegt, ob ein Indexregister automatisch inkrementiert bzw. dekrementiert oder sein Inhalt mit einem der Faktoren 1, 2, 4, 8 skaliert werden soll. Die Felder BReg bzw. IReg enthalten gegebenenfalls die Nummer eines zur Adressierung herangezogenen Basisregisters bzw. Indexregisters.
- Im Bedingungsfeld CC(Condition Code) steht die Codierung einer der im folgenden Unterabschnitt 3.2.3.8 angegebenen Bedingungen. Der Befehl, insbesondere ein Verzweigungsbefehl, wird nur dann ausgeführt, wenn das Überprüfen der Statusbits das Vorliegen dieser Bedingung anzeigt.

Bild 3.2-4: Allgemeines Format eines OpCodes

Besitzt ein Prozessor einen umfangreichen Befehlssatz, einen großen Registersatz und eine weite Palette von Adressierungsarten, so führt die eben beschriebene Codierung zu einem unvertretbar langen OpCode. Aus der Erkenntnis heraus, daß nicht für jeden Befehl alle Felder benötigt werden, teilt man die Befehle so in Gruppen ein, daß die Befehle einer Gruppe jeweils die gleiche Teilmenge an Bitfeldern benutzen. Diese werden auf die ersten Bitpositionen des OpCodes "gefaltet", indem im OpCode alle nicht benötigten Bitfelder weggelassen werden. Dadurch entstehen zwar bei einigen (CISC-)Prozessortypen bis zu zwei Dutzend verschiedene Befehlsformate, aber man erhält im Mittel erheblich kürzere OpCodes. Natürlich wird stets so gefaltet, daß die Anzahl der belegten Bytes des resultierenden OpCodes ganzzahlig ist. Die Faltung ist im Bild 3.2-5 exemplarisch an drei Befehlsgruppen dargestellt.

Bild 3.2-5: Faltung der OpCodes auf verschiedene Befehlsformate

Die Befehlssätze der modernen 16/32-bit-Mikroprozessoren sind so komplex aufgebaut, daß sie im Rahmen unserer Abhandlung nicht mit all ihren Befehlsformaten dargestellt werden können. Deshalb zeigen wir Ihnen in Fallstudien lediglich die Grundform der OpCodes von drei dieser Prozessoren.

Fallstudie 3.2-1: Der Befehlsaufbau der Intel-x86-Prozessoren
Der allgemeine Aufbau eines Befehls bei den x86-Prozessoren der Firma Intel ist im Bild 3.2-6 dargestellt. Bild 3.2-6: Der allgemeine Befehlsaufbau des x86-Prozessors Ein Befehl besteht aus maximal 12 Bytes. Das Operationswort belegt davon je nach Befehlstyp ein oder zwei Bytes. Im Bild werden von den Bitfeldern des Operationswortes nur das D-Bit (Direction), das die Richtung eines Datentransports 'vom/zum Speicher' angibt, und das WL-Bit gezeigt. Das WL-Bit (Word Length) bestimmt die Länge eines im Befehl "unmittelbar" angegebenen Datums oder eines Offsets (Displacement). Dabei wird nur zwischen einer Länge von 8 bit bzw. 16/32 bit unterschieden. Im zweiten Fall wird die tatsächliche Größe des Datums bzw. Offsets durch die hardwaremäßig gewählte Datenbusbreite bestimmt (vgl. Abschnitt 2.7). Die übrigen Bitfelder des Operationswortes haben eine so spezielle Bedeutung, daß sie hier nicht erklärt werden können. Die folgenden beiden Bytes des OpCodes dienen zur Auswahl der Adressierungsart und der dabei benutzten Register. In der einfachsten Form ist lediglich das erste Byte (2a) vorhanden. Das Reg-Feld bestimmt dann, welches Adreßregister benutzt wird. Das R/M-Feld (Register/Mode) hat eine Doppelfunktion, die vom Mod-Feld (Mode) festgelegt wird: Einerseits dient es dazu, für die Registeraustausch-Befehle das zweite benutzte Register festzulegen. Andererseits bestimmt es zusammen mit dem Mod-Feld die gewünschte Adressierungsart. Ist auch das zweite Byte (2b) vorhanden, so wird das Reg-Feld zur Erweiterung des Operationswortes benutzt. Das Register, auf das sich die Adressierung bezieht, wird nun im BReg-Feld bestimmt. Im IReg-Feld kann dazu ein Indexregister angegeben werden, das wahlweise skaliert werden kann. Die Skalierungsgröße wird im SC-Feld (Scale) angegeben. Die Wahl der Adressierungsart geschieht wiederum über das Mod- und das R/M-Feld. Falls ein Offset (Displacement) für die Adreßberechnung erforderlich ist, wird dieser in den folgenden 1 bis 4 Bytes angegeben. In den nächsten Bytes kann ein "unmittelbar adressiertes" Datum mit einer Länge von 1, 2 oder 4 byte auftreten.

Fallstudie 3.2-2: Der Befehlsaufbau der Motorola-Prozessoren MC680X0
Der allgemeine Aufbau eines Befehls für einen 680X0-Prozessor von Motorola ist im Bild 3.2-7 dargestellt. Hier besteht ein Befehl aus maximal 13 16-bit-Wörtern. Im Operationswort wird im Mod-Feld (Mode) die Adressierungsart bestimmt und dazu - falls benötigt im angrenzenden Reg-Feld ein Register angegeben. Beide Felder dienen gemeinsam zur Berechnung der effektiven Adresse eines Operanden. Die kürzesten Befehle besteht nur aus dem Operationswort (Wort 1). Nur bei ihnen werden durch das zweite Reg-Feld ein weiterer Registeroperand und im Feld Op-Mod (Operation Mode) die Breite der Daten (Byte, Wort, Doppelwort) spezifiziert, auf denen der Befehl ausgeführt werden soll. Beide Felder besitzen jedoch für andere Befehle eine ganze Reihe von weiteren Bedeutungen, wie z.B. zur Angabe eines Zählwertes, eines kurzen unmittelbaren Datums, einer Schieberichtung oder eines Coprozessors. Auf diese Bedeutungen wollen wir hier jedoch nicht näher eingehen. Bild 3.2-7: Der allgemeine Befehlsaufbau des 680X0 von Motorola Befehle im Kurzformat besitzen außer dem eigentlichen OpCode im Operationswort noch ein bis zwei Erweiterungswörter (Wörter 2a bzw. 3a). In ihnen wird die Berechnung der Adresse von Datenquelle bzw. Datenziel spezifiziert. Dazu wird im Reg-Feld ein Indexregister angegeben. Das D-Bit (Data) bestimmt, ob dieses aus der Menge der Daten- oder der Adreßregister gewählt werden soll. Das SC-Feld (Scale) bestimmt, mit welchem Wert (1, 2, 4, 8) das (32-bit-)Indexregister skaliert werden soll. Durch das W-Bit (Word) wird festgelegt, ob der gesamte Inhalt des selektierten Indexregisters zur Adreßberechnung herangezogen wird oder aber nur sein niederwertiges (16-bit-)Wort. Dieses wird vorzeichengerecht durch eine Folge von '0'- bzw. '1'-Bits zu einem (32-bit-)Doppelwort ergänzt. Im Displacement-Feld folgt ein 8-bit-Offset. Befehle im Langformat haben außer dem OpCode jeweils bis zu 6 Befehlswörter für die Spezifizierung der Quelle (Wörter 2b1-2b5) und des Zieles (3b1-3b5). Bei der unmittelbaren Adressierung enthalten die Wörter 2b2 bis 2b6 den Operanden. Die Länge des Operanden wird in einem Feld des Operationswortes festgelegt. In diesem Fall entfällt das Wort 2b1. Bei den anderen Adressierungsarten werden im ersten Wort (2b1 bzw. 3b1) alle Parameter für die Adreßberechnung bestimmt, so daß es nach unserer obigen Darstellung (s. Bild 3.2-4) eigentlich zum OpCode gehört. Die linken vier Bitfelder wurden bereits bei der Beschreibung des Kurzformats erwähnt. Die restlichen Felder haben folgende Funktion: BS bestimmt, ob das im Reg-Feld des OpCodes (Wort 1) angegebene Basisregister zur Adreßberechnung herangezogen wird. IS leistet das Gleiche für das im Reg-Feld des Befehlsworts 2b1 bzw. 3b1 selbst angegebene Indexregister. BDS gibt die Länge (0, 1 oder 2 Wörter) des in den Wörtern 2b2 - 2b5 bzw. 3b2 -3b5 folgenden Offsets zum Basisregister an. Durch das Feld I/IS wird zusammen mit dem Mod-Feld im OpCode einerseits die Entscheidung 'Speicher-indirekt/nicht indirekt' getroffen, andererseits die Art der Indizierung 'preindexed/postindexed' und die Länge des zweiten, "äußeren" Offsets (0, 1 oder 2 Wörter) festgelegt (vgl. Bild 3.3-17). Die Wörter 2b2 - 2b5 bzw. 3b2 - 3b5 werden von den Displacements zu Basis- und Indexregister belegt, die jeweils maximal 2 Wörter lang sind.

Fallstudie 3.2-3: Befehlsformate eines RISC-Prozessors
Als Kontrast zu dem sehr komplexen Befehlsaufbau eines typischen CISC-Prozessors, wie Sie ihn in der letzten Fallstudie kennengelernt haben, wollen wir Ihnen nun zeigen, wie einfach - im Prinzip - der Befehlsaufbau eines RISC-Prozessors sein kann. Dazu haben wir einen der "Stammväter" dieser Prozessorklasse, den RISC II herausgesucht, der Anfang der 80er Jahre an der Universität Berkeley entwickelt wurde. Dieser Prozessor kannte nur sechs verschiedene Befehlsformate, die im Bild 3.2-8 skizziert sind. Auffällig ist hier eine allgemeine Eigenschaft der RISC-Prozessoren, daß alle Befehle eine gleiche Länge haben, also in einer festen Anzahl von Bits (i.d.R. 32 Bits), codiert sind. Dies wird hauptsächlich durch das unterstützte Dreiadreß-Format möglich, bei dem alle Operanden in Registern vorliegen müssen. Im Speicher müssen alle Befehle (als aligned Data) stets an Doppelwort-Grenzen ausgerichtet sein, d.h. ihre Speicheradressen müssen durch 4 teilbar sein. Bild 3.2-8: Befehlsformate des RISC II Das unter a) dargestellte Format wird von allen Befehlen benutzt, die im Dreiadreß-Format zwei Operanden zu einem Ergebnis verknüpfen, in symbolischer Kurzschreibweise: RD := RS1 op RS2 , wobei 'op' eine Operation, RD das Zielregister (D: Destination), RS1 und RS2 die beiden Quellregister (S: Source) bezeichnen. Zu diesen Befehlen gehören insbesondere diejenigen zur Ausführung arithmetisch/logischer Operationen. In LOAD/STORE-Befehlen dienen die Register RS1 und RS2 zur Berechnung der effektiven Operandenadresse, in Sprung- und Verzweigungsbefehlen zur Berechnung der Zieladresse nach der im Abschnitt 3.3 beschriebenen Register-relativen Adressierung mit Index. Format b) ermöglicht die arithmetisch/logische Verknüpfung eines Registerinhalts mit einem unmittelbar im Befehl angegebenen Operanden der Länge 13 bit: RD := RS1 op #<Operand>. In LOAD/STORE-Befehlen gibt die Summe des Inhalts von Register RS1 und des unmittelbar im Befehl angegebenen Datums (als Offset) die effektive Adresse des Operanden, in Sprung- und Verzweigungsbefehlen die Zieladresse nach der Register-relativen Adressierungsart an. Im Format c) werden alle Befehle mit Programmzähler-relativer Adressierung angegeben, wobei der im Befehl stehende konstante Wert als 19-bit-Offset dient. Durch einen LOAD-Befehl wird der Inhalt des so adressierten Speicherwortes ins Register RD geladen, durch einen STORE-Befehl der Registerinhalt von RD dort abgelegt. Als Ausnahme existiert ein Befehl, durch den das unmittelbar im Befehl angegebene Datum in die höherwertigen 19 Bits von RD transportiert wird. Befehle, die eines der Formate d), e) oder f) besitzen, werden nur ausgeführt, wenn die durch die vier Bits CC gewählte logische Bedingung erfüllt ist. Die möglichen Bedingungen stimmen zum großen Teil mit den in Tabelle 3.2-10 dargestellten überein. Falls in einem der Befehl CC=0 gesetzt ist, so wird der Befehl unbedingt ausgeführt. Format d) wird für eine bedingte, Programmzähler-relative Verzweigung benutzt. Die Formate e) und f) werden einerseits von Befehlen für bedingte Verzweigungen, andererseits für bedingte Rücksprünge aus Unterprogrammen oder Interruptroutinen benutzt. Sie unterscheiden sich nur in den Adressierungsarten für die Berechnung der Zieladressen: Register-relativ mit Index bzw. Offset. Das Bit SCC (Set Condition Code) wird in den Befehlen gesetzt, die das Carry-Flag auswerten, (z.B. der Addierbefehl ADDC). Durch das Bit IM (immediate) wird festgelegt, ob im Befehl ein unmittelbares Datum bzw. ein Offset oder aber ein weiteres Operandenregister angegeben ist.

### 3.2.3 Darstellung der verschiedenen Befehlsgruppen |

Die Befehlssätze der meisten Mikroprozessoren stellen dem Benutzer die in der Tabelle 3.2-1 beschriebenenBefehlsgruppen zur Verfügung. In den nachfolgenden Tabellen werden die Befehle jeder Befehlsgruppe durch gebräuchliche mnemotechnische Abkürzungen angegeben. Je nach Komplexität verwirklichen die Mikroprozessoren jedoch nur einen mehr oder weniger großen Ausschnitt des im weiteren beschriebenen Befehlssatzes. Darüber hinaus verfügen sie aber häufig über weitere Spezialbefehle, die in den folgenden Tabellen nicht aufgeführt sind. Die ersten Befehlsgruppen der folgenden Darstellung bezeichnen wir vereinfachend als Basis-Befehlsgruppen, da sie mehr oder weniger von allen Mikroprozessoren - bis hinab zu den einfachsten Mikrocontrollern - verarbeitet werden. Einige Komponenten moderner Mikroprozessoren, wie die Gleitpunkt-Einheit (Floating-Point Unit) oder die Multimedia-Rechenwerke, besitzen eigene Befehlssätze, die wiederum aus verschiedenen Befehlsgruppen zusammengesetzt sind. Um unnötige Querverweise zu vermeiden, werden wir diese Befehlssätze am Ende des Abschnitts geschlossen behandeln. Neben den beschriebenen Funktionen besitzen moderne Prozessoren z.T. noch über eine große Anzahl weiterer Befehle, die zum Beispiel der Speicherverwaltung (durch die Memory Management Unit - MMU), der Steuerung der schnellen Cache-Zwischenspeicher oder der Kontrolle der elektrischen Leistungsaufnahme (System Management Mode - SSM) dienen. Diese wollen wir hier nicht beschreiben. Auf besondere Befehle zur digitalen Signalverarbeitung werden wir erst bei der Beschreibung der zu ihrer Ausführung implementierten speziellen Hardware-Komponenten von DSPs eingehen.

Tabelle 3.2-1: Die unterscheidbaren Befehlsgruppen

Abschnitt | Befehlsgruppen
| Basisbefehlsgruppen der Integer-Rechenwerke
3.2.3.1 | Arithmetische Befehle
3.2.3.2 | Logische Befehle
3.2.3.3 | Schiebe- und Rotationsbefehle
3.2.3.4 | Flag- und Bit-Manipulationsbefehle
3.2.3.5 | Zeichenketten- und Blockbefehle
| Basisbefehlsgruppen des Steuerwerks
3.2.3.6 | Datentransportbefehle
3.2.3.7 | Ein-/Ausgabe-Befehle
3.2.3.8 | Sprung- und Verzweigungsbefehle
3.2.3.9 | Unterprogramm- und Rücksprünge, Software-Interrupts
3.2.3.10 | Systembefehle
3.2.3.11 | Zusammengesetzte Befehle
| Befehlsgruppen der Gleitpunkt-Einheiten
3.2.3.12 | Arithmetische Befehle, Vergleichsbefehle, Transferbefehle,
| Befehlsgruppen der Multimedia-Rechenwerke
3.2.3.13 | Integer-Multimedia-Befehle
3.2.3.14 | Gleitpunkt-Multimedia-Befehle

3.2.3.1 Arithmetische Befehle (Tabelle 3.2-2)

Diese Befehle erlauben insbesondere die Ausführung der vier Grundrechenarten: +, -, ×, /. Zum Teil können diese Operationen in hexadezimaler oder dezimaler Arithmetik durchgeführt werden. Multiplikation und Division können wahlweise mit vorzeichenbehafteten (IMUL, IDIV; I: Integer) und vorzeichenlosen Operanden (MUL, DIV) durchgeführt werden. Bei Prozessoren, die nur im Hexadezimalmodus (Dualzahlen) rechnen können, wird durch die Befehle DAA bzw. DAS (Decimal Adjust Addition/Subtraction) das Ergebnis einer arithmetischen Operation in eine BCD-Zahl umgewandelt. Dazu benutzen die Befehle das Übertrags- und das Hilfs-Übertragsbit (Half-Carry Flag, s. Abschnitt 2.4.1).

Tabelle 3.2-2: Arithmetische Befehle

Mnemocode | Bedeutung
ABS | Absolutbetrag bilden (Absolute)
ADD | Addition ohne Berücksichtigung des Übertrags (Add)
ADC | Addition mit Berücksichtigung des Übertrags (Add with Carry)
CLR | Löschen eines Registers oder Speicherwortes (Clear)
CMP | Vergleich zweier Operanden (Compare)
COM | bitweises Invertieren eines Operanden (Einerkomplement) (Complement)
DAA, DAS | Umwandlung eines dualen Ergebnisses in eine Dezimalzahl
| nach Addition oder Subtraktion (Decimal Adjust Addition/Subtraction)
DEC | Register oder Speicherwort dekrementieren (Decrement)
IDIV, DIV | Division& (Divide)
INC | Register oder Speicherwort inkrementieren (Increment)
IMUL, MUL | Multiplikation (Multiply)
NEG | Vorzeichenwechsel im Zweierkomplement (Negate)
SUB | Subtraktion ohne Berücksichtigung des Übertrags (Subtract)
SBC, SBB | Subtraktion mit Berücksichtigung des Übertrags (Subtract with Carry/Borrow)

Des weiteren gibt es Befehle für das Inkrementieren und Dekrementieren der Operanden in Speicherwörtern oder Registern. Diese Operanden können außerdem bitweise invertiert oder negiert (Vorzeichenwechsel) sowie auf ihren Absolutbetrag abgebildet werden. Darüber hinaus können Operanden gelöscht, d.h. auf den Wert 0 zurückgesetzt werden. Besondere Bedeutung haben die COMPARE-Befehle, die zum Vergleich zweier Operanden dienen. Dazu werden diese subtrahiert, jedoch so, daß auch im Zweiadreß-Format keiner der Operanden durch das Ergebnis verändert wird. In Abhängigkeit vom Ergebnis werden aber die Flags im Statusregister gesetzt oder zurückgesetzt. Diese stehen dann für nachfolgende "bedingte" Befehle zur Verfügung (vgl. die Verzweigungsbefehle im Unterabschnitt 3.2.3.8).

3.2.3.2 Logische Befehle (Tabelle 3.2-3)

Diese Befehle veranlassen die bitweise logische Verknüpfung zweier Operanden. Standardmäßig kann eine UND-, ODER- bzw. Antivalenz-Verknüpfung durchgeführt werden. Manchmal ist auch eine Äquivalenz-Verknüpfung vorgesehen. Die monadische Operation NOT invertiert jedes Bit eines Operanden und stimmt also mit der im Unterabschnitt 3.2.3.1 aufgeführten Inversion (Einerkomplement) überein.

Tabelle 3.2-3: Logische Befehle

Mnemocode | Bedeutung
AND | UND-Verknüpfung zweier Operanden
OR | ODER-Verknüpfung zweier Operanden
EOR | Antivalenz-Verknüpfung zweier Operanden (Exclusive Or)
NOT | Invertierung eines (Booleschen) Operanden

3.2.3.3 Schiebe- und Rotationsbefehle (Tabelle 3.2-4)

Diese Befehle führen die im Abschnitt 2.4.1 beschriebenen Schiebe- und Rotationsoperationen durch.

Tabelle 3.2-4: Schiebe- und Rotationsbefehle

Mnemocode | Bedeutung
SHF | Verschieben eines Registerinhaltes (Shift)
| insbesondere:
ASL | arithmetische Linksverschiebung Arithm. Shift Left)
ASR | arithmetische Rechtsverschiebung Arithm. Shift Right)
LSL | logische Linksverschiebung (Logical Shift Left)
LSR | logische Rechtsverschiebung (Logical Shift Right)
ROT | Rotation eines Registerinhaltes (Rotate)
| insbesondere:
ROL | Rotation nach links (Rotate Left)
RCL | Rotation nach links durchs Übertragsbit (Rotate with Carry Left)
ROR | Rotation nach rechts (Rotate Right)
RCR | Rotation nach rechts durchs Übertragsbit (Rotate with Carry Right)
SWAP | Vertauschen der beiden Hälften eines Registers

Es wurde bereits darauf hingewiesen, daß bei einfachen Prozessoren diese Operationen durch die ALU des Integer-Rechenwerks ausgeführt werden und leistungsfähigere Prozessoren, insbesondere auch DSPs, eine spezielle Schiebeeinheit (Barrel Shifter) zur Bearbeitung dieser Befehle besitzen. Im ersten Fall kann eine Verschiebung oder Rotation nur um eine Bitposition pro Taktzyklus ausgeführt werden. Im zweiten Fall kann die Anzahl der Bitpositionen im Befehl angegeben werden, um die der Operand in einem einzigen Taktzyklus verschoben werden soll. Der Inhalt eines Registers oder eines Speicherwortes kann auf vielfältige Weise manipuliert werden. Die Verschiebung oder Rotation kann dabei nach links oder rechts geschehen. Dabei muß bei der Verschiebung nach rechts zwischen dem Vorzeichen-erhaltenden arithmetischen und dem logischen Verschieben unterschieden werden. Beim Linksschieben unterscheiden sich beide Operationen nicht, dennoch werden i.d.R. zwei verschiedene Assemblerbefehle dafür angeboten, die aber in denselben Maschinenbefehl übersetzt werden.
Rotier- und Schiebebefehle können insbesondere auch dazu benutzt werden, ein bestimmtes Bit des Operanden dadurch zu überprüfen, daß man es in das Übertragsbit bringt. Durch (arithmetische) Operationen, die dem Rotier- bzw. Schiebebefehl folgen, kann jedoch das Übertragsbitverändert werden, bevor es ausgewertet wird. Daher benutzt die im Bild 3.2-9 dargestellte Variante ein weiteres Hilfsflag X(Extension Flag), in dem das "Ergebnis" der Rotationsoperation zwischengespeichert und das nur durch diese Befehle beeinflußt wird.

Bild 3.2-9: Darstellung der Rotationsoperationen mit Hilfsflag

3.2.3.4 Flag- und Bit-Manipulationsbefehle (Tabelle 3.2-5)

Diese Befehle gestatten einerseits das gezielte Setzen, Rücksetzen oder Invertieren der Bedingungs-Flags im Statusregister oder der Flags im Steuerregister des Prozessors. Dazu gehören fast immer das Übertragsbit CF und das Interrupt Flag IF.
Andererseits können durch diese Befehle bestimmte einzelne Bits in einem Register oder einem Speicherwort gesetzt, zurückgesetzt oder invertiert werden. Da die kleinste adressierbare Speichereinheit ein Byte ist, wird bei den Bitbefehlen, die auf einen Operanden im Speicher angewandt werden, natürlich stets wenigstens ein Byte gelesen und dann im Prozessor daraus ein bestimmtes Bit extrahiert. Das Ändern eines einzelnen Bits in einem Speicherwort bedingt daher zunächst das Lesen dieses Wortes, die Manipulation des Bits im Prozessor und das Rückschreiben des Wortes in den Speicher. Die Nummer des angesprochenen Bits wird durch den Inhalt eines Registers oder "nmittelbar" im Befehl angegeben. Sie ist bei einem Operanden, der in einem Register liegt, durch die Breite des Registers, bei einem Operanden im Speicher durch den höchsten Bitindex (des Speicherwortes) beschränkt. Durch den TST/BT-Befehl kann der Zustand eines einzelnen Bits im Operanden ermittelt werden. Durch diesen Befehl werden nur die Flags im Statusregister beeinflußt. Der Befehl BT[S,R,C] testet ein bestimmtes Bit und setzt es danach auf '1' oder '0' oder invertiert es.

Tabelle 3.2-5: Flag- und Bit-Manipulationsbefehle

Mnemocode | Bedeutung
E<f> | Setzen eines Bedingungs-Flags (Set)
CL<f> | Löschen eines Bedingungs-Flags (Clear)
CM<f> | Invertieren eines Bedingungs-Flags (Complement)
BSET | Setzen eines Bits (Bit Set)
BCLR | Rücksetzen eines Bits (Bit Clear)
BCHG | Invertieren eines Bits (Bit Change)
TST, BT | Prüfen eines bestimmten Flags oder Bits (Test)
BT[S,R,C] | Prüfen eines bestimmten Flags oder Bits mit anschließendem Setzen (S), Rücksetzen (R) oder Invertieren (C)
BF... | Bitfeld-Befehle,
| insbesondere:
BFCLR | Zurücksetzen der Bits auf '0' (Clear)
BFSET | Setzen der Bits auf '1' (Set)
BFFFO | Finden der ersten '1' in einem Bitfeld (Find First One)
BSF, BSR | Scannen eines Bitfeldes: vorwärts/rückwärts (Bit Scan Forward/Reverse)
BFEXT | Lesen eines Bitfeldes (Extract)
BFINS | Einfügen eines Bitfeldes (Insert)
(<f> Abkürzung für ein Flag, z.B. C Carry Flag)

In Erweiterung dazu bieten einige Prozessoren die Möglichkeit, ein Feld zusammenhängender Bits im Speicher durch einen einzigen Befehl zu lesen oder zu verändern (Bit Field, Bit String). (Diese Bitfelder wurden im Abschnitt 3.1 beschrieben.) Bedeutung haben diese Befehle insbesondere bei der Verarbeitung von Audio- oder Videodaten, wo die Bitfelder z.B. den digitalisierten Wert eines akustischen Signals oder die Repräsentation eines Bildschirmpunktes bzw. seiner Farben enthalten.
Die Assemblersyntax eines Bitfeld-Befehles ist z.B. folgendermaßen darstellbar:
BFEXT <Adresse>{Offset:Länge},Dn .
Durch die Adresse wird genau ein Byte im Speicher selektiert. Danach wird ein Bit bestimmt, das vom höchstwertigen Bit (MSB) des selektierten Bytes die durch den Offset vorgegebene Bitdistanz hat. Mit diesem Bit beginnend, werden die durch die (Bitfeld-)Länge angegebenen Bits in das Register Dn geladen. Es existieren Befehle zum Setzen (BFSET) oder Löschen (BFCLR) eines bestimmten Bits im Bitfeld. Durch den Befehl BFFFO kann die höchstwertige '1' in einem Bitfeld gesucht werden. In der Realisierung BSF/BSR kann die Richtung des Suchvorgangs (MSB -->LSB, LSB-->MSB) gewählt werden.
3.2.3.5 Zeichenketten- und Blockbefehle (Tabelle 3.2-6)

Hierunter sind die verschiedensten Befehle zusammengefaßt, die sich nicht auf einzelne Operanden, sondern auf einen ganzen Block von Operanden beziehen. Dazu gehören insbesondere die im Abschnitt 3.1 beschriebenen Bitketten und Datenblöcken (Bit Strings, Character Strings). Datenblöcke bestehen aus Bytes (B), Wörtern (W) oder Doppelwörtern (D). Es gibt Befehle zum Transport von Datenblöcken zwischen dem Speicher und den Registern im Prozessor oder den Peripheriebausteinen. Andere Befehle erlauben den Vergleich von Datenblöcken, das Kopieren von solchen Blöcken oder das Suchen eines bestimmten Operanden in einem Block. Die Startadressen und die Längen der Blöcke müssen vor Ausführung der Befehle in die Register des Prozessors eingeschrieben werden. Mit jedem Aufruf des Befehls wird dann genau ein Element des Blockes bearbeitet. Zur Bearbeitung des gesamten Blockes muß der Befehl durch den Präfix 'REP..' (Repeat, s. Abschnitt 3.2.3.11) zur Ausführung in einer Schleife ergänzt werden. Der Inhalt des Längenregisters wird mit jeder Befehlsausführung automatisch erniedrigt, bis er den Wert 0 erreicht hat.

Tabelle 3.2-6: String- oder Blockbefehle

Mnemocode | Bedeutung
MOVS[B,W,D] | Transferieren eines Blocks (Move String)
INS[B,W,D] | Einlesen eines Blocks von der Peripherie (Input String)
OUTS[B,W,D] | Ausgabe eines Blocks an die Peripherie (Output String)
CMPS[B,W,D] | Vergleich zweier Blöcke (Compare String)
COPS[B,W,D] | Kopieren eines Blocks (Copy String)
SCAS[B,W,D] | Suchen eines Datums (Scan String)

3.2.3.6 Datentransportbefehle (Transferbefehle, Tabelle 3.2-7)

Diese Befehle übertragen ein Datum von einem Quellort zu einem Zielort im Mikroprozessor-System. Quelle oder Ziel kann jeweils ein Speicherwort, ein Prozessorregister oder ein Register in einem Peripheriebaustein sein.

Tabelle 3.2-7: Transferbefehle

Mnemocode | Bedeutung
LD | Laden eines Register (Load)
LEA | Laden eines Registers mit der Adresse eines Operanden (Load Effective Address)
ST | Speichern des Inhalts eines Register (Store)
MOVE | Übertragen eines Datums (in beliebiger Richtung) (Move)
EXC | Vertauschen der Inhalte zweier Register bzw.
| eines Registers und eines Speicherwortes (Exchange)
TFR | Übertragen eines Registerinhalts in ein anderes Register (Transfer)
PUSH | Ablegen des Inhalts eines oder mehrerer Register im Stack
PULL (POP) | Laden eines Registers bzw. mehrerer Register aus dem Stack
STcc | Speichern eines Registerinhaltes, falls Bedingung cc (n. Tabelle 3.2-10) erfüllt ist

Man kann unterscheiden:

- Laden eines Registers mit einer Konstante bzw. Ablegen einer Konstante in einem Speicherwort.
- Austauschen der Inhalte zweier Register bzw. eines Registers und eines Speicherwortes.
- Laden eines Registers aus dem Speicher bzw. Ablegen eines Registerinhaltes im Speicher. Dabei kann man weiter die folgenden Spezialfälle unterscheiden:
  - Laden eines Registers aus dem Stack bzw. Speichern des Inhalts eines Registers im Stack. Diese Befehle können manchmal auch auf mehrere Register gleichzeitig angewandt werden.
  - Laden eines Registers mit der (effektiven) Adresse eines Operanden (und nicht mit dem Operanden selbst !). Dieser Befehl erlaubt es, die Adresse eines Operanden erst zur Laufzeit des Programms festzustellen. Dadurch ist es u.a. möglich, Programme so zu schreiben, daß sie überall im Speicher ablauffähig sind ("verschiebbarer Programmcode" - Relocatable Program).
- Übertragen des Inhalts eines Speicherwortes in ein anderes Speicherwort. Der MOVE-Befehl verursacht zwei Transferoperationen: Zunächst wird der Operand aus dem Speicher in den Datenbuspuffer und von dort zurück in den Speicher, gewöhnlich aber an eine andere Stelle, übertragen.
- Bedingte Transferbefehle, die nur dann ausgeführt werden, wenn eine bestimmte Bedingung erfüllt ist. Diese Bedingungen sind weiter unten in der Tabelle 3.2-10 zusammengefaßt.
  Zum Beispiel:
  STORE NOT EQUAL(STNE): "Speichere den Registerinhalt, falls er von 0 verschieden ist."

3.2.3.7 Ein-/Ausgabe-Befehle (Tabelle 3.2-8) Wie bereits mehrfach erwähnt, verfügen einige Mikroprozessoren über spezielle Ein-/Ausgabe-Befehle zum Datenaustausch mit den Peripheriebausteinen. Jeder dieser Befehle aktiviert das im Abschnitt 2.7 beschriebene Ausgangssignal (M/IO#) des Prozessors, das zur Anwahl der Peripheriebausteine herangezogen werden kann.
Tabelle 3.2-8: Ein-/Ausgabe-Befehle

Mnemocode | Bedeutung
IN, READ | Laden eines Registers aus einem Peripheriebaustein
OUT, WRITE | Übertragen eines Registerinhalts in einen Peripheriebaustein

3.2.3.8 Sprung- und Verzweigungsbefehle (Tabelle 3.2-9)

Diese Befehle erlauben es, die konsekutive Ausführung der Befehle eines Programmes zu unterbrechen und an einer anderen Programmstelle fortzufahren (vgl. auch Bild 3.2-2). Sprungbefehle werden dabei stets durchgeführt. Das Sprungziel wird durch seine absolute (logische) Adresse angegeben. Verzweigungsbefehle werden jedoch nur in Abhängigkeit von einer im Befehl gewählten Bedingung (cc) ausgeführt. Das Sprungziel wird in der Regel durch seine Distanz zum aktuellen Programmzähler bestimmt ("Programmzähler-relativer Sprung"). Ist die Bedingung nicht erfüllt, wird mit dem Befehl fortgefahren, der im Speicher unmittelbar hinter dem Verzweigungsbefehl folgt.

Tabelle 3.2-9: Sprung- und Verzweigungsbefehle

Mnemocode | Bedeutung
JMP | unbedingter Sprung zu einer Adresse (Jump)
Bcc | Verzweigen, falls die Bedingung cc erfüllt ist (Branch)
BRA | Verzweigen ohne Abfrage einer Bedingung (Branch Always)

Einfache Bedingungen (cc werden durch die Flags des Statusregisters vorgegeben. Sie sind im oberen Teil der Tabelle 3.2-10 dargestellt. Im unteren Teil der Tabelle sind Bedingungen aufgeführt, die nach einem COMPARE-Befehl (s. Tabelle 3.2-2) zum Teil aus mehreren Flags des Statusregisters hergeleitet werden und Aussagen über das Verhältnis der beiden Operanden gestatten. Dabei wird zwischen nicht-vorzeichenbehafteten Operanden und vorzeichenbehafteten Operanden im Zweierkomplement unterschieden. Einsetzen aller Bedingungen cc in den Mnemocode Bcc ergibt die möglichen Verzweigungsbefehle. Dazu bieten viele Prozessoren noch den Befehl BRA(Branch Always), der zwar das Format eines Verzweigungsbefehls besitzt, jedoch einen nicht bedingten relativen Sprung veranlaßt.
Bei den aus den Flags abgeleiteten Bedingungen muß der Assemblerprogrammierer strikt unterscheiden, ob die durch den COMPARE-Befehl verglichenen Operanden vorzeichenlose oder vorzeichenbehaftete Integer-Zahlen repräsentieren sollen. Für beide Interpretationen existieren gesonderte Verzweigungsbefehle.

Beispiel:
Wird auf 'größer als' verglichen, so ist für

- vorzeichenlose Zahlen $A0 > $7E und BHI (Branch Higher) der richtige Befehl,
- vorzeichenbehaftete Zahlen $7E > $A0 und BGT (Branch Greater than) der richtige Befehl.

Tabelle 3.2-10: Gebräuchliche Bedingungen für Verzweigungsbefehle

cc | Bedingung | Bezeichnung
CS | CF=1 | Branch on Carry Set
CC | CF=0 | Branch on Carry Clear
VS | OF=1 | Branch on Overflow
VC | OF=0 | Branch on not Overflow
EQ | ZF=1 | Branch on Zero/Equal
NE | ZF=0 | Branch on not Zero/Equal
MI | SF=1 | Branch on Minus
PL | SF=0 | Branch on Plus
PA | PF=1 | Branch on Parity/Parity Even
NP | PF=0 | Branch on not Parity/Parity Odd
nicht vorzeichenbehaftete Operanden
LO | CF=1 (vgl. CS) | Branch on Lower than
LS | CF v ZF = 1 | Branch on Lower or Same
HI | CF v ZF = 0 | Branch on Higher than
HS | CF=0 (vgl. CC) | Branch on Higher or Same
vorzeichenbehaftete Operanden
LT | SF ¹ OF = 1 | Branch on Less than
LE | ZF Ú (SF ¹ OF) = 1 | Branch on Less or Equal
GT | ZF Ú (SF ¹ OF) = 0 | Branch on Greater than
GE | SF ¹ OF = 0 | Branch on Greater or Equal
(Bezeichnungen: ¹ Antivalenz, Ú logisches ODER)

3.2.3.9 Unterprogramm- und Rücksprünge, Software-Interrupts (Tabelle 3.2-11)

Durch einen Unterprogrammsprung wird ein abgeschlossener Programmteil aufgerufen, dessen Startadresse bzw. ein Offset dazu im Befehl angegeben ist. Dieser Aufruf kann unbedingt unter Angabe einer absoluten Adresse (Jump to Subroutine JSR) oder aber in Abhängigkeit einer der in Tabelle 3.2-10 aufgeführten Bedingungen cc relativ zum Programmzähler (mit Angabe eines Offsets) geschehen (BSRcc). Der Rücksprung in das aufrufende Programm wird durch den Befehl RTS (Return from Subroutine) bewirkt.
Im Abschnitt 2.3, wurde schon gesagt, daß im Unterschied zu einem Unterprogrammaufruf bei einem Software-Interrupt keine Startadresse im Befehl angegeben wird. Statt dessen ist der aufzurufenden Interruptroutine eine Startadresse im Speicher entweder implizit fest zugeteilt, oder diese wird durch die Angabe eines Index im Befehl aus einer Ausnahmevektor-Tabelle ausgewählt. Der Rücksprung aus einer Interruptroutine geschieht mit dem Befehl RTI (Return from Interrupt) oder RTE (Return from Exception).

Tabelle 3.2-11: Unterprogramm- und Rücksprünge, Software-Interrupts

Mnemocode | Bedeutung
JSR, CALL | unbedingter Sprung in ein Unterprogramm Jump to Subroutine)
BSRcc | Verzweigung in ein Unterprogramm, falls cc gilt (Branch to Subroutine)
RTS | Rücksprung aus einem Unterprogramm (Return from Subroutine)
SWI,TRAP,INT | Unterbrechungsanforderung durch Software (Software Interrupt)
RTI, RTE | Rücksprung aus einer Unterbrechungsroutine (Return from Interrupt/Exception)

3.2.3.10 Systembefehle (Systemkontrolle, Tabelle 3.2-12)

In dieser Rubrik findet man die Befehle, die der Synchronisation der Komponenten eines Mikroprozessor-Systems dienen (System Control). Der einfachste Befehl NOP erhöht lediglich den Programmzähler (PC), wofür er eine gewisse Ausführungszeit benötigt. Er wird deshalb in entsprechend großer Anzahl häufig dazu benutzt, um kleinere, feste Zeitspannen zu überbrücken.
Durch den WAIT-Befehl besteht die Möglichkeit, eine Programmausführung solange zu unterbrechen, bis an einem bestimmten Eingang des Prozessors ein Signal auftritt. Zu diesen Eingängen gehört z.B. der BUSY-Eingang, über den ein Coprozessor dem Mikroprozessor anzeigen kann, wann er eine Operation beendet hat. Danach wird das Programm an der Wartestelle fortgesetzt.
Beim SYNC-Befehl erwartet der Prozessor an einem (beliebigen) Interrupteingang eine Unterbrechungsanforderung und setzt nach deren Eintreten seine Arbeit mit der zugeordneten Interruptroutine fort.
Durch den RESET-Befehl kann am RESET-Ausgang des Prozessors ein Rücksetzsignal für alle angeschlossenen Peripheriebausteine erzwungen werden.

Tabelle 3.2-12: Systembefehle

Mnemocode | Bedeutung
NOP | keine Operation, nächsten Befehl ansprechen (No Operation)
WAIT | Warten, bis ein Signal an einem speziellen Eingang auftritt
SYNC | Warten auf einen Interrupt
HALT, STOP | Anhalten des Prozessors, Beenden jeder Programmausführung
RESET | Ausgabe eines Rücksetzsignals für die Peripheriebausteine
SVC | (geschützter) Aufruf des Betriebssystemkerns (Supervisor Call)

Neben den bisher beschriebenen Systembefehlen verfügen die modernen 16/32-bit-Prozessoren über weitere Systembefehle, die insbesondere der Kontrolle der verschiedenen Arbeitszustände (Benutzermodus, Systemmodus), der Steuerung der Speicherverwaltung und der Kommunikation und Kooperation mit einem anderen (Co-)Prozessor dienen. Auf sie wird nicht hier, sondern erst bei der Beschreibung dieser Komponenten eingegangen.

3.2.3.11 Zusammengesetzte Befehle (Tabelle 3.2-13)

Diese Befehle kombinieren mehrere Befehle aus den bisher beschriebenen Gruppen. Ihr Sinn liegt darin, durch die Zusammenfassung Speicherplatz für den Maschinencode und Ausführungszeit zu sparen.
Die "Hochsprachen-Befehle" unterstützen einen Compiler bei der Umsetzung von komplexen Befehlen, wie sie in einer höheren Programmiersprache üblich sind, in eine Folge von Maschinenbefehlen. Zu ihnen kann man auch die oben beschriebenen Block- und Stringbefehle zählen, die durch Voranstellen des Präfix 'REP..' (Repeat) eine auf diese Datenstrukturen eingeschränkte Schleifensteuerung in Hardware ermöglichen: Die Stringoperation wird solange wiederholt, bis der Inhalt eines bestimmten Registers den Wert 0 hat. Der Wert dieses Registers wird bei jeder Ausführung der Stringoperation um 1 dekrementiert
Der LOOP-Befehl vereinfacht das Programmieren von allgemeinen Schleifen: Vor der Ausführung wird der Inhalt eines Registers dekrementiert und nur dann eine Programmverzweigung durchgeführt, wenn die im Befehl angegebene Bedingung für dieses Register gilt.
Durch den CASE-Befehl kann eine Kette von Abfragen durch mehrere bedingte Branch-Befehle dadurch vermieden werden, daß für das Vorliegen unterschiedlicher Bedingungen mehrere Sprungziele angegeben werden können (Multiway Branch).
Die beiden Befehle CHECK und INDEX erleichtern die Arbeit mit mehrdimensionalen Feldern (Arrays). Der erste überprüft, ob ein Index innerhalb vorgegebener Grenzen liegt und speichert im positiven Fall die Differenz zum unteren Grenzwert in einem bestimmten Register. Werden die Bereichsgrenzen unter- bzw. überschritten, wird eine Programmunterbrechnung ausgeführt (Trap, s. Abschnitt 2.3). Der Befehl INDEX berechnet für den Index (i,j) eines zweidimensionalen Feldes den Offset zur Basisadresse des Feldes nach der Formel:

Offset = Zeilenlänge × (i-1) + j .
Tabelle 3.2-13: Zusammengesetzte Befehle

Mnemocode | Bedeutung
DBcc | Dekrementieren eines Registers und bedingte Verzweigung, falls
| cc (nach Tabelle 3.2-10) erfüllt ist (Decrement and Branch)
| "Hochsprachen-Befehle"
LOOP | Abarbeiten einer Schleife
REP ... | Wiederholen einer Stringoperation (Repeat)
CASE | Verzweigung mit mehreren Sprungzielen
CHECK | Überprüfen, ob ein Feldindex in den vorgegebenen
(BOUND) | Grenzen liegt
INDEX | Umrechnung eines Feldindexes in einen Adressen-Offset
| "Test und Modifizier-Befehle"
TAS, BTS | Prüfen eines Bits mit anschließendem Setzen (Bit Test and Set)
BTR | Prüfen eines Bits mit anschließendem Rücksetzen (Bit Test and Reset)
BTC | Prüfen eines Bits mit anschließendem Invertieren (Bit Test and Complement)
LOCK ... | Verhindert die Unterbrechung eines Befehls

Für die "Test- und Modifizier-Befehle" ist charakteristisch, daß sie als eine nicht unterbrechbare Operation ausgeführt werden. Deshalb darf der Systembus zwischen den einzelnen Teilbefehlen nicht von einer anderen Komponente des Systems belegt werden. Dazu zählen z.B. andere (Co-)Prozessoren oder Systemsteuerbausteine (vgl. Kapitel 4). Dadurch wird verhindert, daß zwischen der Abfrage eines Speicherwortes oder eines speziellen Bits darin und der folgenden Modifikation eine andere Komponente dieses Wort bzw. Bit verändert. In synchronen Bussystemen wird die Nicht-Unterbrechbarkeit durch das Aktivieren eines speziellen Prozessorausgangs erreicht, der z.B. mit LOCK bezeichnet wird und den anderen Komponenten mitteilt, daß der Systembus für mehr als einen Speicherzyklus benötigt wird. Der Befehl LOCK aktiviert diesen Ausgang für die Dauer des folgenden Maschinenbefehls und sorgt somit dafür, daß dieser nicht unterbrochen werden kann. Bei asynchronen Bussystemen wird das im Abschnitt 2.7, beschriebene Ausgangssignal AS (Address Strobe), das das Vorliegen einer gültigen Adresse auf dem Adreßbus anzeigt, für die gesamte Ausführungsdauer des Befehls aktiviert und sperrt solange den Bus gegen Zugriffe anderer Komponenten.

Beispiel Ein Beispiel für die Notwendigkeit des LOCK-Befehls ist der BTC-Befehl, mit dem der Zustand eines Bits in einem Speicherwort abgefragt und invertiert werden kann. Mit der Befehlsfolge
LOCK BTC <Adresse>,<Bitnummer>
können Semaphore zur Synchronisation der Zugriffe mehrerer Prozessoren auf ein gemeinsames Betriebsmittel realisiert werden. Dazu kann z.B. vereinbart werden, daß ein Prozessor nur dann auf das Betriebsmittel zugreifen darf, wenn das Bit den Wert '1' hat. Jeder zugriffswillige Prozessor testet dieses Bit. Findet er den Wert '0', so muß er warten und den Zugriff später noch einmal versuchen. Findet er jedoch den Wert '1', so invertiert er sofort das Bit und kann das Betriebsmittel benutzen. Nach Abschluß dieser Nutzung setzt er das Bit wieder auf '1' und gibt dadurch das Betriebsmittel wieder frei. In diesem Beispiel verhindert die Nicht-Unterbrechbarkeit der Befehlsfolge, daß zwischen der Erkennung des '1'-Zustandes und der Invertierung des Bits ein anderer Prozessor, der ebenfalls den Wert '1' liest, bereits auf das Betriebsmittel zugreift.
3.2.3.12 Gleitpunktbefehle Die Befehle der Gleitpunkt-Einheit (Floating-Point Unit - FPU) eines Mikroprozessors lassen sich in Gruppen einteilen, die wie Sie den folgenden Tabellen entnehmen können - zum Teil den Basis-Befehlsgruppen des Integer-Rechenwerkes entsprechen. Wir werden die Befehlsgruppen getrennt besprechen. Im Befehlssatz eines modernen Mikroprozessors sind bestimmte Befehle für die Gleitpunkt-Einheit reserviert. Ihre OpCodes beginnen meistens mit einer spezifischen Bitkombination. Üblich sind z.B. '1111' (=$F) oder '11011' (=$1B). In Assemblerschreibweise werden ihre Mnemocodes meist durch das Präfix 'F' (Floating Point) gekennzeichnet:
F<Mnemocode> .
Den Mnemocodes werden gewöhnlich Postfixe angehängt, die das Datenformat spezifizieren, auf das die Operation angewandt werden soll, also z.B.:

F<Mnemocode>S | einfach-genaues | Gleitpunktformat, (single)
F<Mnemocode>D | doppelt-genaues Gleitpunktformat, | (double)
F<Mnemocode>X | erweitert-genaues Gleitpunktformat, | (extended)
Mnemocode>P | gepacktes BCD-Format. | (packed)

1. Arithmetische Gleitpunktbefehle (Tabelle 3.2-14)

   Die arithmetischen Gleitpunktoperationen lassen sich in die Grundoperationen (Primary Operations) und die daraus abgeleiteten Operationen (Derived Operations) unterteilen.

   Tabelle 3.2-14: Die arithmetischen Befehle der Gleitpunkt-Einheit

   Mnemocode | Bedeutung
   | 1. Grundoperationen
   FADD | Addition (Add)
   FSUB | Subtraktion (Subtract)
   FSUBR | umgekehrte Subtraktion (Subtract Reverse)
   FMUL | Multiplikation (Multiply)
   FDIV | Division (Divide)
   FDIVR | umgekehrte Division (Divide Rreverse)
   FMOD | Rest einer Division (Modulo)
   FRNDINT | Rundung zu einer ganzen Zahl (Round Integer)
   FSQRT | Quadratwurzel (Square Root)
   FABS | Absolutbetrag (Absolute)
   FCMP | Vergleich zweier Operanden (Compare)
   FGETEXP | Extrahieren des Exponenten (Get Exponent)
   FGETMAN | Extrahieren der Mantisse (Get Mantissa)
   FEXTRACT | Extrahieren von Exponent u. Mantisse (Extract Exponent and Significand)
   FCHS | Vorzeichenwechsel (Change Sign)
   | 2. abgeleitete Operationen
   FAXXX | Arcus-Funktionen, XXX=COS, SIN, TAN, TANH
   FXXX | Trigonometrische Funktionen,
   | XXX = COS, SIN, TAN, COSH, SINH, TANH, SINCOS
   FnTOX | Potenzieren der Basis n: nX , n=2, e, 10
   F2XM1 | 2X - 1
   FYL2X | Y * log2 X
   FYL2XP1 | Y * log2 (X+1)

   Zu den Grundoperationen gehören insbesondere die Addition, Subtraktion, Multiplikation und Division. Aus dem Bereich der DSPs stammt der Befehl SUBR (Subtract Reverse), bei dem die beiden Opernanden vor der Subtraktion vertauscht werden. Dieser Befehl vermeidet eine u.U. notwendige, zeitaufwendige Vertauschung der Operanden in ihren Registern. Ähnliches gilt auch für den Divisionsbefehl FDIVR (Divide Reverse). Zu den abgeleiteten Operationen gehören die trigonometrischen, logarithmischen und exponentiellen mathematischen Funktionen. Durch den Befehl FRNDINT kann eine Gleitpunktzahl zu einer ganzen Zahl gerundet werden. Dabei wird durch die Bits RC im Steuerregister der FPU festgelegt, welche der im Abschnitt 3.1 beschriebenen Rundungsmöglichkeiten benutzt werden soll. Mit den FGET...-Befehlen kann der Exponent oder die Mantisse eines Gleitpunktoperanden selbst in eine Gleitpunktzahl umgewandelt werden. Der Befehl FXTRACT faßt beide Befehle in einem zusammen. Neben den beschriebenen Befehlen existiert noch eine Reihe weiterer, die gleichzeitig einen der Operanden aus dem "Stack" der Gleitpunktregister (POP) entfernen oder eine gemischte Verknüpfung von Gleitpunkt- und Integer-Operanden ermöglichen.
   Neben den Grundoperationen führt die Einheit abgeleitete Operationen aus, die in Tabelle 3.2-14 angegeben sind und deshalb hier nicht näher beschrieben werden müssen.

2. Transferbefehle (Tabelle 3.2-15)

   Durch diese Befehle wird ein Operand in ein Datenregister der FPU übertragen oder von dort gelesen. Dabei kann durch den Befehl FLDconst auch ein Operand aus dem Konstanten-ROM der Gleitpunkt-Einheit gelesen werden. Als Konstante kommen in Frage: +1.0, +0.0, p , log2 e, loge 2, log2 10, log10 2. (const = 1, Z, PI, L2E, LN2, L2T, LG2). Durch den Befehl FMOVEM kann eine spezifizierte Menge von Datenregistern der FPU mit einem einzigen Befehl geladen oder abgespeichert werden.

   Tabelle 3.2-15: Die Transferbefehle der Gleitpunkt-Einheit

   Mnemocode | Bedeutung
   FLD | Laden eines Gleitpunktregisters mit einem Operanden aus dem
   | Speicher oder einem Mikroprozessor-Register (load)
   FST | Lesen eines Gleitpunktregisters und Übertragung in den
   | Speicher oder ein Mikroprozessor-Register (Store)
   FLDconst | Laden eines Gleitpunktregisters aus dem Konstanten-ROM
   FMOVE(M) | Übertragen eines/mehrerer Operanden in die/aus der Gleitpunkt-Einheit
   FCMOVcc | Bedingter Transport eines Gleitpunktregisterinhalts, falls Bedingung cc gilt
   FXCH | Austausch zweier Gleitpunktregister
   FSAVE | Retten aller Systemregister der Gleitpunkt-Einheit
   FRESTORE | Laden aller Systemregister der Gleitpunkt-Einheit

   Durch die Befehle FSAVE bzw. FRESTORE werden alle Systemregister der FPU in den Speicher übertragen oder von dort geladen. Die Befehlspaare FMOVEM / FSAVE bzw. FMOVEM / FRESTORE müssen zur Umschaltung zwischen verschiedenen Programmen in einem Multitasking-Betriebssystem benutzt werden, für die der Inhalt aller FPU-Register, d.h. der Daten- und Systemregister, im Speicher abgelegt bzw. von dort wieder eingelagert werden muß. Bei Prozessoren, die nur einen gemeinsamen Registersatz für die FPU und die MMX-Einheit besitzen, müssen diese Umschaltbefehle ebenfalls benutzt werden, wenn zwischen den beiden "Rechenarten" 'Gleitpunkt' bzw. 'MMX' gewechselt werden soll. Dies verlangsamt unnötigerweise die Ausführung von Anwendungen, die darauf aufbauen. Der Befehl FXCH ermöglicht den Austausch des Inhalts zweier Gleitpunktregister. Der Befehl FCMOVcc (Conditionally Move) transportiert den Inhalt eines Gleitpunktregisters nur dann, wenn die Bedingung cc gilt. Für cc kommen dabei die Bedingungen "=, ¹ , <, nicht <, £ , nicht £ " in Frage. Auch hier gibt es wieder Befehle, die einen Speicherbefehl mit dem Entfernen aus dem Stack (POP) verbinden oder auf Integer-Zahlen wirken.

3. Befehle zur Programmkontrolle (Tabelle 3.2-16)

   Die folgenden Befehle werden in Abhängigkeit von den Zustandsbits CC im Statusregister der FPU ausgeführt (s. Abschnitt 2.4.5).
   Aus den Statusbits CC kann eine der in Tabelle 3.2-17 mit cc bezeichneten Bedingungen abgeleitet werden. Dabei ist zu beachten, daß als Ergebnis einer Operation auch die 'Zahl' "+/- unendlich" oder aber "keine gültige Zahl" (NaN) herauskommen kann. Deshalb gelten nicht mehr die bei den Integer-Rechenwerken üblichen Verneinungen der Bedingungen. So ist zum Beispiel die Verneinung von

   | "größer" | (greater than)
   nicht | "kleiner oder gleich" | (less than or equal)
   sondern | "nicht größer" | (not greater than).

   Außerdem müssen nun nicht mehr alle Operanden vergleichbar sein. Das führt z.B. zu der bei ganzen Zahlen unsinnigen, weil stets erfüllten Bedingung:

   | "größer, kleiner oder gleich", |

   die nur dann erfüllt ist, wenn beide Operanden vergleichbar sind.

   Tabelle 3.2-16: Die Befehle der Gleitpunkt-Einheit zur Steuerung des Programmablaufs

   Mnemocode | Bedeutung
   FCOM | Vergleich zweier Gleitpunktzahlen (Compare)
   FUCOM | Ungeordneter Vergleich zweier Gleitpunktzahlen (Compare)
   FBcc | Mikroprozessor verzweigt, falls in FPU cc gilt (Branch)
   FDBcc | FPU testet, ob die Bedingung cc gilt; falls cc gilt,
   | dekrementiert der Mikroprozessor eine Zählvariable und verzweigt,
   | falls Zählvariable >= 0 (Decrement and Branch)
   FScc | Mikroprozessor setzt ein bestimmtes Flag-Byte im Speicher auf 11..11,
   | falls in FPU cc gilt, sonst setzt er es auf 00..00 zurück (Set)
   FTRAPcc | Mikroprozessor führt einen Trap aus, falls in FPU cc gilt

   Durch den Befehl FCOM werden die Inhalte zweier Gleitpunktregister miteinander verglichen und die Flags des Statusregisters in Abhängigkeit vom Ergebnis gesetzt. Der Befehl FUCOM führt die gleiche Operation auf ungeordneten Operanden aus. Beide Befehle existieren auch in Varianten, die gleichzeitig einen oder beide Operanden aus dem Stack der Gleitpunktregister entfernen (POP) oder Integer-Zahlen vergleichen. Der Befehl FScc kann dazu benutzt werden, das Ergebnis eines Operandenvergleichs für eine spätere Auswertung in einem Byte des Speichers als Flag abzulegen. Der Befehl FTRAPcc veranlaßt den Aufruf einer Ausnahme-Behandlungsroutine, falls die Bedingung erfüllt ist. Die Startadresse (Vektor) dieser Routine ist in der Interrupt-Vektortabelle an einer fest vorgegebenen Position abgelegt.

   Tabelle 3.2-17: Die abgeleiteten Bedingungen (¬ = logische Verneinung, v = ODER)

   cc | Bedingung |
   EQ | = | equal
   NE | ¬= | not equal
   GT | > | greater than
   NGT | ¬> | not greaterthan
   GE | >= | greater than or equal
   NGE | ¬(>=) | not (greater than or equal)
   LT | < | less than
   NLT | ¬< | not less than
   LE | <= | less than or equal
   NLE | ¬(<=) | not (less than or equal)
   GL | < v > | greater or less
   NGL | ¬(> v <) | not (greater or less)
   GLE | > v < v = | greater, less or equal
   NGLE | ¬(> v < v =) | not (greater, less or equal)

4. Steuerbefehle (Tabelle 3.2-18)

   Diese Befehle dienen z.B. zur Initialisierung der Gleitpunkt-Einheit, zur Übertragung eines Wortes in das Steuerregister der FPU und zum Lesen ihres Statusregisters. Durch FFREE kann ein Gleitpunktregister freigegeben werden. Der Befehl FCLEX dient in einer Ausnahmeroutine dazu, die Trap Flags im Statusregister nach der Überprüfung auf Fehlerbedingungen zurückzusetzen, um so eine erneute Unterbrechung durch die gleiche Fehlerursache zu verhindern. Der Befehl FNCLEX erfüllt dieselbe Operation, aber ohne eine Überprüfung auf eine Fehlerbedingung. Bei FPUs, die ihren Registersatz als Stack betreiben, kann der Stackpointer im Statusregister durch die Befehle FINCSTP, FDECSTP erhöht oder erniedrigt werden.

   Tabelle 3.2-18: Steuerbefehle

   Mnemonik | Bedeutung
   FINIT | Initialisieren der FPU (Initialize)
   FFREE | Freigeben eines Gleitpunkt-Registers (Free)
   FLDCW, FNCLEX | Laden des Steuerregisters (Control Word CW) (Load)
   FSTrr | Übertragen des Registers rr in den Speicher, (Store)
   | rr=CW: Steuerregister, rr=SW: Statusregister
   FCLEX | Rücksetzen der Trap Flags im Statusregister (Clear)
   FNOP | keine Operation (No Operation)
   FINCSTP | Erhöhen des Stackpointers der FPU (Increment Stackpointer)
   FDECSTP | Erniedrigen des Stackpointers der FPU (Decrement Stackpointer)

Selbsttestaufgabe S3.2-1: (–>Lösungsvorschlag)
a) Geben Sie die Formel für die Berechnung des Restes der Division zweier Operanden Aund B an. Geben Sie den Rumpf eines Assemblerprogramms zur Berechnung dieser Formel durch die anderen arithmetischen Operationen an. b) Wie sieht das Ergebnis der Operationen FGETEXP und FGETMAN im 32-bit-Format nach dem IEEE-754-Standard aus, wenn man sie auf die Dezimalzahl Z = -1.625×2160 anwendet.

Exkurs 3.2.1: Adressierung von Coprozessoren
Einige Prozessoren, die über keine integrierte FPU verfügen, unterstützen den simultanen Einsatz mehrerer Coprozessoren. Bei diesen muß dann in jedem Coprozessor-Befehl eine Nummer zur eindeutigen Identifizierung des gewünschten Coprozessors angegeben werden. Für den Typ 68020 von Motorola ist im Bild 3.2-10 der allgemeine Aufbau des OpCodes eines Coprozessor-Befehls skizziert. Jeder Coprozessor-Befehl wird durch vier '1'-Bits in den höchstwertigen Positionen gekennzeichnet. Wie im Assemblercode beginnen daher alle Befehle auch im Maschinencode mit dem Präfix $F... . Bild 3.2-10: Befehlsformat bei mehreren Coprozessoren Dann folgen drei Bits, die zur Auswahl eines von 8 möglichen Coprozessoren benutzt werden (Coprocessor Identification - Cp-ID). Für den Arithmetik-Prozessor ist die Bitkombination '001' reserviert. Die nächsten drei Bits des OpCodes spezifizieren den Typ des Arithmetikbefehls. Die restlichen Bits bestimmen in Abhängigkeit vom Befehlstyp z.B. die benötigten Register oder die gewünschte Adressierungsart.

3.2.3.13 Multimedia-Befehle für Integer-Zahlen

In diesem Unterabschnitt werden wir Befehle zur Verarbeitung von ganzzahligen Multimedia-Daten besprechen. Dabei werden wir uns auf die Befehle der MMX-Einheit der Intel-Prozessoren beschränken, die erfreulicherweise auch von den Prozessoren der Firma AMD (Analog Micro Devices) unterstützt werden und damit im PC-Bereich eine überragende Rolle spielen. Auf ähnliche Befehlssatz-Erweiterungen bei RISC-Prozessoren werden wir nicht eingehen.
In der folgenden Tabelle 3.2-19 sind die Befehle der MMX-Einheit aufgeführt. Der Buchstabe 'P' am Anfang der Befehle ist als 'gepackter Befehl' (packed) bzw. 'paralleler Befehl' zu interpretieren. Wie im Abschnitt 2.4.5, beschrieben, können diese Befehle wahlweise auf gepackten Bytes (B), Wörtern (W), Doppelwörtern (D) oder Quadwords (Q) ausgeführt werden. Für jeden Befehl sind in der Tabelle die erlaubten Möglichkeiten angegeben, wobei mehrere Möglichkeiten in eckige Klammern gesetzt sind. Die gewünschte Form der Operanden (B, W, D, Q) wird - unter Weglassen der Klammern - an den Mnemocode des Befehls angehängt. Im Mnemocode wird durch den Buchstaben 'U' (unsigned) eine Operation mit vorzeichenlosen Operanden, durch 'S' (signed) eine Operation mit vorzeichenbehafteten Operanden angezeigt. Nach der Angabe 'vorzeichenlos/vorzeichenbehaftet' kann durch den Buchstaben 'S' festgelegt werden, daß die Operation mit Sättigung des Ergebnisses ausgeführt werden soll. Wiederholend sei noch einmal darauf hingewiesen, daß bei allen Operationen kein Übertrag zwischen den einzelnen gepackten Daten, also zwischen den Bytes, Wörtern oder Doppelwörtern, auftrifft. Zu beachten ist auch, daß alle dyadischen (zweistelligen) Operationen (mit Ausnahme von PSABW) parallel über Paare von Daten aus ihren beiden Operanden ausgeführt werden, nicht über mehrere Teildaten eines einzigen Operanden.

Tabelle 3.2-19: Befehle der MMX-Einheit

Mnemocode | Bedeutung
| arithmetische Operationen
PADD[B,W,D] | Addition mit Überlauf (Wrap-Around)
PADDS[B,W] | vorzeichenbehaftete Addition mit Sättigung
PADDUS[B,W] | vorzeichenlose Addition mit Sättigung
PSADBW | Summe der absoluten Abweichungen der Operanden-Bytes (o. Vorz.)
PSUB[B,W,D] | Subtraktion mit Überlauf
PSUBS[B,W] | vorzeichenbehaftete Subtraktion mit Sättigung
PSUBUS[B,W] | vorzeichenlose Subtraktion mit Sättigung
PMULHW | Multiplikation, höherwertiges (H-)Wort als Ergebnis
PMULLW | Multiplikation, niederwertiges (L-)Wort als Ergebnis
PMADDWD | Multiplikation mit Addition der Produkte
PAVG[B,W] | Durchschnittsbildung
PMAXSW | Maximumsbildung über vorzeichenbehaftete Wörter
PMAXUB | Maximumsbildung über vorzeichenlose Bytes
PMINSW | Minimumsbildung über vorzeichenbehaftete Wörter
PMINUB | Minimumsbildung über vorzeichenlose Bytes
PMOVMSKB | Packen der 8 Vorzeichenbits eines 8-byte-Datums in ein Integer-Register
| logische Operationen
PAND | bitweise Und-Verknüpfung
PANDN | bitweise, negierte Und-Verknüpfung (NAND)
POR | bitweise Oder-Verknüpfung
PXOR | bitweise Antivalenz-Verknüpfung (XOR)
| Schiebeoperationen
PSLL[W,D,Q] | logisches Linksschieben, Anzahl der Positionen in MMX-Register oder unmittelbar im Befehl angegeben
PSRL[W,D,Q] | logisches Rechtsschieben, Anzahl der Positionen in MMX-Register oder unmittelbar im Befehl angegeben
PSRA[W,D] | arithmetisches Rechtsschieben, Anzahl der Positionen in MMX-Register oder unmittelbar im Befehl angegeben
| Vergleichsoperationen
PCMPEQ[B,W,D] | Vergleich auf Gleichheit
PCMPGT[B,W,D] | Vergleich auf 'größer als'
| Umwandlungsoperationen
PACKUSWB | Packen vorzeichenbeh. Wörter in vorzeichenlose Bytes, m. Sättigung
PACKSS[WB,DW] | Packen von vorzeichenbehafteten Wörtern in vorz.b. Bytes, von vorzeichenbehafteten Doppelwörtern in vorz.b. Wörter, mit Sättigung
PUNPCKL[BW,WD,DQ] | Erweitern der niederwertigen Bytes zu Wörtern, niederw. Wörter zu Doppelwörtern bzw. des niederw. Doppelwortes zu einem Quadword
PUNPCKL[BW,WD,DQ] | Erweitern der höherwertigen Bytes zu Wörtern, höherw. Wörter zu Doppelwörtern bzw. des höherw. Doppelwortes zu einem Quadword
| Datentransfer
MOV[D,Q] | Datentransport zu oder aus einem MMX-Register
PEXTRW | Extrahieren eines Worts aus MMX-Reg., Transport in Integer-Register
PINSRW | Einfügen eines Wortes in ein MMX-Reg. aus einem Integer-Register
PSHUFW | beliebige Vertauschung der 4 Wörter eines Operanden
| Prozeßwechsel (FP- & MMX- State Management)
EMMS | Leeren aller MMX-Register im Tag-Word

1. Arithmetische Befehle Wie im Abschnitt 2.4.5, beschrieben, können die Addition (PADD...) und Subtraktion (PSUB...) mit Überlauf, vorzeichenlos-gesättigt und vorzeichenbehaftet-gesättigt durchgeführt werden. Der Befehl PSABW bildet paarweise über die (vorzeichenlosen) 8 Bytes der beiden Operanden die Absolutbeträge der Differenzen und summiert anschließend diese Werte auf. Sind O1 = (B1,7,.., B1,0) und O2 = (B2,7,..,B2,0), so folgt also für das Ergebnis E:
   E = Summe i=0,..,7 |B2,i - B1,i | .

   Die Multiplizierbefehle PMULHW, PMULLW bilden - paarweise und vierfach parallel - die Produkte aus den 16-bit-Wörtern der Operanden. Von den berechneten 32-bit-Ergebnissen werden dann jeweils die höherwertigen (PMULHW) bzw. niederwertigen (PMULLW) 16 Bits als Ergebnisse abgespeichert. Der Befehl PMADDWD (Multiply and Add Word/Doubleword) bilden ebenfalls vier 32-bit-Produkte über die Wörter der Operanden, addiert danach aber die beiden höherwertigen bzw. niederwertigen Produkte und speichert die Ergebnisse als 32-bit-Doppelwörter ab (vgl. Abschnitt 2.4.5). Durch Setzen eines der Operandenwerte auf 0 ist mit diesem Befehle auch eine Multiplikation 16x16-->32 bit möglich.
   Mit Hilfe des PAVG-Befehls kann paarweise über die (als vorzeichenlose Zahlen aufgefaßten) Bytes oder Wörter der beiden Operanden der Durchschnitt gebildet werden. Entsprechend ermitteln die Befehle PMAXSW, PMAXUB, PMINSW, PMINUB die Maxima bzw. Minima über Paare von vorzeichenbehafteten Wörtern bzw. vorzeichenlosen Bytes der Operanden. Der Befehl PMOVMSKB (Move Byte Mask) ermittelt für jedes Byte eines gepackten 8-Byte-Datums das Vorzeichen (durch Lesen des MSBs), packt diese Vorzeichen zu einem Byte zusammen und speichert dieses in den niederwertigen Bits eines der in Abschnitt 2.6, beschriebenen x86-Registern .

2. Logische Befehle

   Die logischen Befehle unterscheiden sich in keiner Weise von den logischen Befehlen eines Integer-Rechenwerks. Sie werden bitweise auf 64-bit-Quadwords ausgeführt und müssen keinerlei Rücksicht auf bestimmte gepackte Datenformate nehmen, da keine Überträge zwischen den Stellen auftreten. Eine kleine Besonderheit ist, daß es hier keinen Befehl zur Inversion (NOT) gibt. Dieser kann durch die Befehle PANDN oder PXOR nachgebildet werden.

3. Schiebebefehle

   Die Funktionen der Schiebe- und Rotationsbefehle stimmen exakt mit denen der entsprechenden Befehle des Integer-Rechenwerkes überein - hier aber jeweils eingeschränkt auf die einzelnen Teildaten einer gepackten Datenstruktur. Das heißt, daß wiederum keinerlei Übertrag zwischen diesen Teildaten stattfindet. Beim logischen Links- bzw. Rechtsschieben sowie beim arithmetischen Linksschieben werden dementsprechend an den "Nahtstellen" zwischen den Teildaten '0'-Bits eingezogen und die herausgeschobenen Bits gehen verloren. Beim arithmetischen Rechtsschieben wird an allen diesen Nahtstellen das Vorzeichen des angrenzenden Teildatums durch Erhaltung des MSBs regeneriert. Die Anzahl der Bitpositionen, um die die einzelnen Teildaten verschoben werden sollen, muß unmittelbar im Befehl oder in einem Register angegeben werden.

4. Vergleichsbefehle

   Als Vergleichsbefehle stehen lediglich der Vergleich auf Gleichheit und auf 'größer als' zur Verfügung. Die Wirkung dieser Befehle auf gepackte Operanden wurde bereits im Abschnitt 2.4 beschrieben. Als Ergebnis des Vergleichs wird eine "Maske" erzeugt, die für alle Teildaten, für die die Vergleichsbedingung richtig war, eine Folge von '1'-Bits besitzt (hexadezimal $FF..FF), für alle Teildaten mit dem Ergebnis falsch eine Folge von '0'-Bits (hexadezimal $00..00). Diese Ergebnismasken können zur Selektion bestimmter Teildaten und zur Verschmelzung der Teildaten verschiedener Operanden mit Hilfe der logischen Befehle dienen.

5. Umwandlungsbefehle

   Diese Befehle bieten vier Grundbefehle, mit deren Hilfe die Teildaten der gepackten Operanden auf vielfältige Weise verkürzt, miteinander verschränkt oder verlängert werden können. Die Verlängerung kann z.B. durch Voranstellen von '0'-Bits (Zero-extended) oder des Vorzeichenbits (Sign-extended). Dadurch sind unterschiedliche Formatanpassungen insbesondere für die Verarbeitung von graphischen oder Audio-Daten möglich. Zu bemerken ist, daß den 64-bit-Operanden erst durch die Anwendung der Befehle eine bestimmte Datenstruktur aufgeprägt wird, so daß in einer Folge von Befehlen auf denselben Daten die in den Befehlen angegebene Datenlänge (Byte, Wort, Doppelwort, Quadword) beliebig gewählt werden kann.
   Der Befehl PACKUSWB (Pack unsigned with Saturation) betrachtet die Teildaten seiner 4-Wort-Operanden als vorzeichenbehaftete Zahlen und begrenzt diese Zahlen auf ihre untere 8 Bits. 16-bit-Zahlen größer als 255 werden dabei zum Wert 255 ($FF) gesättigt, negative Zahlen jedoch auf den Wert $00 abgeschnitten. Die erzeugten 2x4 Bytes der beiden Operanden werden zu einem 8-byte-Operanden gepackt, wobei der erste Operand die höherwertigen, der zweite die niederwertigen Bytes belegt.
   Der Befehl PACKSS (Pack signed with Saturation) führt die beschriebenen Operationen in analoger Weise auf gepackten 4-Wort-Operanden oder 2-Doppelwort-Operanden aus, wobei die auf ihre niederwertige Hälfte verkürzten Teildaten jedoch als vorzeichenbehaftete Zahlen interpretiert und entsprechend gesättigt werden. Das heißt, daß bei der ggf. erforderlichen Sättigung positive 16-bit-Zahlen auf $7F bzw. 32-bit-Zahlen auf $7FFF, negative 16-bit-Zahlen auf $80 und negative 32-bit-Zahlen auf $8000 gesetzt werden. Im Bild 3.2-11 ist dies für den Befehl PACKSSDW skizziert.

   Bild 3.2-11: PACKSSDW (S: Sättigung)

   Durch die Befehle PUNPCKL bzw. PUNPCKH (Unpack) werden die Teildaten an den niederwertigen (L) bzw. höherwertigen (H) Positionen der beiden gepackten Operanden zu einem einzigen Datum zusammengepackt. Die Zusammenfassung geschieht in verzahnter Weise (interleaved), d.h. die Teildaten der Operanden belegen abwechseln die Positionen des Ergebnisregisters. Dies ist im Bild 3.2-12 für den Befehl PUNPCKHWD (Unpack Word to Doubleword) skizziert, durch den vier 16-bit-Zahlen zu zwei 32-bit-Zahlen verknüpft werden.

   Bild 3.2-12: Wirkung des Befehls PUNPCKHWD

6. Transferbefehle

   Der Befehl MOV transportiert ein Datum zwischen einem MMX-Register und einem (universellen) 32-Bit-Register des Prozessors oder einer Speicherzelle des Hauptspeichers. Der Transport kann in beide Richtungen - also schreibend oder lesend - geschehen. 32-bit-Daten werden in den unteren 32 Bits des MMX-Registers abgelegt, die oberen 32 werden mit '0' aufgefüllt (Zero Extension). Durch PEXTRW wird ein im Befehl spezifiziertes 16-bit-Wort eines MMX-Registers in die unteren 16 Bits eines universelles Registers abgelegt, wobei die höherwertigen 16 Bits unverändert bleiben. Der Befehl PINSRW transportiert das untere 16-bit-Wort eines universellen 32-bit-Registers in die ausgewählte Wortposition eines MMX-Registers. Durch den Befehl PSHUFW können die vier 16-bit-Wörter eines MMX-Registers oder einer (64-bit-)Speicherzelle in eine von 24 möglichen Permutationen umgestellt und in einem (anderen) MMX-Register abgelegt werden.

7. Prozeßwechselbefehl

   Diese Gruppe enthält nur den Befehl EMMS, mit dem nach einer Folge von MMX-Befehlen der Zustand des Registersatzes für die nachfolgende Abarbeitung von Gleitpunktbefehle zurückgesetzt wird. Dieser Befehl ist notwendig, wenn sich MMX- und Gleitpunkt-Einheiten dieselben Register teilen. Seine Wirkung besteht im wesentlichen im Rücksetzen des Tag Words (s. Bild 6.8.**), in dem für jedes Registers sein Zustand festgehalten ist.

3.2.3.14 Multimedia-Befehle für Gleitpunktzahlen

Im Abschnitt 2.4.5 wurden spezielle Rechenwerke zur Bearbeitung von gepackten Gleitpunktzahlen für Multimedia-Anwendungen beschrieben. Je nach Prozessortyp werden dazu zwei (AMD-Prozessoren) oder vier (Intel-Prozessoren) 32-bit-Zahlen (Single Precision) nach dem IEEE-754-Standard zu einem Operanden zusammengefaßt und in 64-bit- bzw. 128-bit-Registern abgelegt. In der Tabelle 3.2-20 sind die speziellen Befehle für diese Rechenwerke aufgeführt. Da die Befehlssätze für beide eben genannten Prozessorfamilien zu einem großen Teil dieselben oder ähnliche Befehle besitzen, haben wir hier wieder auf die Darstellung in Fallstudien verzichtet. Vergleichbare Befehlssatz-Erweiterung von RISC-Prozessoren werden nicht behandelt.

1. Arithmetische Befehle

   Diese Befehle können wahlweise parallel auf gepackten Gleitpunktoperanden oder aber auf einzelnen "skalaren" Daten ausgeführt werden. Dazu muß an den Mnemocode des Befehls die entsprechende Endung PS (Packed Single-Precision) oder SS (Scalar Single-Precision) angehängt werden. Skalare Befehle wirken stets nur auf die niederwertigen Teildaten der Operanden, lassen also alle anderen Teildaten unverändert. Neben den Grundrechenarten Addition, Subtraktion, Multiplikation und Division findet man hier noch die Funktionen Quadratwurzelziehen, Minimums- und Maximumsbildung, wobei die beiden letztgenannten wieder über Paare von Teildaten der beiden Operanden ausgeführt werden. Dies ist anders bei den folgenden Befehlen: PFACC bzw. PFNACC (Packed Floating-Point (Negate) Accumulate) berechnet die Summen bzw. Differenzen der beiden Teildaten jedes Operanden für sich und packt dann die berechneten Ergebnisse zu einem 64-bit-Datum zusammen. PFNACC (Packed Floating-Point Mixed Positive-Negative) Accumulate) berechnet aus den Teildaten des ersten Operanden die Differenz, aus denen des zweiten die Summe und packt die Ergebnisse zu einem 64-bit-Datum zusammen. Die Subtraktion ist durch den Befehl PFSUBR wiederum mit Vertauschung der Reihenfolge der Teiloperanden möglich.

2. Vergleichsbefehle

   Der Befehl CMP (Compare) vergleicht Paare von 32-bit-Gleitpunktdaten und liefert für jeden 32-bit-Vergleich das 32-bit-Feld '11...11', wenn der Vergleich ein wahres Ergebnis liefert, und '00..00', wenn das Ergebnis "falsch" ist. Dabei kann auf eine von 12 Bedingungen cc verglichen werden, die im wesentlichen mit denen aus Tabelle 3.2-17 übereinstimmen. Der Befehl COMISS vergleicht lediglich die niederwertigen (skalaren) Teildaten der Operanden und setzt - dem Ergebnis entsprechend - im Statusregister des Prozessors das Carry-, Zero- und Paritäts-Flag. Alle anderen Flags werden auf '0' zurückgesetzt.

3. Logische Befehle

   Diese Befehle unterscheiden sich in keiner Weise von den entsprechenden Befehlen der Integer- oder Gleitpunkt-Rechenwerke.

   Tabelle 3.2-20: Befehle eines Multimedia-Gleitpunktrechenwerks

   Mnemocode | Bedeutung
   | arithmetische Operationen mit einfach-genauen Gleitpunktzahlen
   ADD[PS,SS], PFAD | gepackte Addition - skalare Addition
   SUB[PS,SS], PFSUB | gepackte Subtraktion - skalare Subtraktion
   PFSUBR | gepackte Subtraktion mit Vertauschen der Operanden (R - Reverse)
   MUL[PS,SS], PFMUL | gepackte Multiplikation - skalare Multiplikation
   DIV[PS,SS], PFRCP | gepackte Division - skalare Division
   SQRT[PS,SS], PFRSQRT | gepackte Quadratwurzel - skalare Quadratwurzel
   MAX[PS,SS], PFMAX | gepackte Maximumsbildung - skalare Maximumsbildung
   MIN[PS,SS], PFMIN | gepackte Minimumbildung - skalare Minimumbildung
   PFACC | Addition über gepackte Operanden mit Packen der Summen
   PFNACC | Subtraktion über gepackte Operanden mit Packen der Differenzen
   PFPNACC | kombinierte Addition und Subtraktion über gepackte Operanden
   | Vergleichsoperationen mit einfach-genauen Gleitpunktzahlen
   CMP[PS,SS] | gepackter Vergleich - skalarer Vergleich
   [U]COMISS | (un-)geordneter skalarer Vergleich, Setzen der Statusflags
   | Logische Operationen mit einfach-genauen Gleitpunktzahlen
   ANDPS | gepackte bitweise Und-Verknüpfung
   ANDNPS | gepackte bitweise verneinte Und-Verknüpfung
   ORPS | gepackte bitweise ODER-Verknüpfung
   XORPS | gepackte bitweise Antivalenz-Verknüpfung
   | Umwandlungsbefehle auf gepackten/skalaren Gleitpunktzahlen
   CVTPI2PS, PI2FW | gepackte Integer-Zahlen in Gleitpunktzahlen
   CVTSI2SS | skalare Integer-Zahl in Gleitpunktzahl
   CVTPS2PI, PF2IW | gep. Gleitpunktzahlen in Integer-Zahlen, mit Vorzeichenerweiterung
   CVTTPS2PI | gepackte Gleitpunktzahlen in Integer-Zahlen, Abschneiden des Rests
   CVTSS2SI | skalare Gleitpunktzahl in Integer-Zahl, mit Vorzeichenerweiterung
   CVTTSS2PI | skalare Gleitpunktzahlen in Integer-Zahlen, Abschneiden des Rests
   UNPCK[H,L]PS | Entpacken der höher-/niederwertigen Gleitpunktzahlen
   | Datentransfer
   MOV[A,U]PS | Transfer von gepackten ausgerichteten (aligned)/ nicht ausgerichteten (unaligned) Gleitpunktzahlen zwischen Speicher und Register
   MOVSS | Transfer von skalaren Gleitpunktzahlen zw. Speicher und Register
   MOV[H,L]PS | Transfer von gepackten Gleitpunktzahlen von/zu H/L-Registerhälften
   MOV[HL,LH]PS | Transfer von gepackten Gleitpunktzahlen zw. H- und L-Registerhälften
   MOVMSKPS | Transfer der Maskenbits in ein Integer-Register
   PSWAPD | Vertauschen der beiden gepackten Gleitpunktzahlen
   SHUFPS | Permutieren der gepackten Gleitpunktzahlen
   PREFETCH | vorzeitiges Laden von Operanden in den Cache
   SFENCE | bringt Schreiboperationen in richtige Reihenfolge
   | Steuerbefehle
   STMXCSR | Abspeichern des Steuer- und Statusregisters der Multimedia-Einheit
   LDMXCSR | Laden des Steuer- und Statusregisters der Multimedia-GP-Einheit
   FXRSTOR | Abspeichern des Zustandes der FPU, MMX-Einheit und Multimedia-GP-Einheit in den Speicher
   FXSAVE | Laden des Zustandes der FPU, MMX-Einheit und Multimedia- GP-Einheit aus dem Speicher

4. Umwandlungsbefehle

   Der Befehl PI2FW (Packed Integer to Floating-Point) wandelt zwei vorzeichenbehaftete 16-bit-Integer-Zahlen, die an den geradzahligen Positionen (0,2) des Quellregisters stehen, in zwei 32-bit-Gleitpunktzahlen um und packt sie in ein 64-bit-Zielregister. PF2IW (Packed Floating-Point to Integer) transformiert Gleitpunktzahlen in 16-bit-Integer-Zahlen, die durch Ergänzung mit ihrem Vorzeichen auf 32 bit erweitert werden (Sign Extension). Dabei werden Werte, die außerhalb des darstellbaren positiven Zahlenbereichs (-32768,..,32767) liegen auf die entsprechende Bereichsgrenze ($FFFF8000 bzw. $0000 7FFF) gesättigt. Der nicht ganzzahlige Anteil der gewandelten Zahlen wird abgeschnitten (Truncation).
   Die Befehle CVT... (der Intel-Prozessoren) ermöglichen eine Datenaustausch mit kombinierter Konvertierung zwischen der MMX-Integer-Einheit und dem Multimedia-Gleitpunktrechenwerk, die über jeweils einen eigenen Satz von acht Registern verfügen. CVTPI2PS (Convert Packed Integer to Packed Single-Precision Floating-Point) wandelt die zwei Integer-Zahlen in einem MMX-Register in zwei 32-bit-Gleitpunktzahlen um und packt sie in die unteren beiden Positionen eines 128-bit-Registers der Multimedia-GP-Einheit. Die Zahlen an den beiden oberen Positionen bleiben unverändert. CVTSI2PS (Convert Scalar Integer to Packed Single-Precision Floating-Point) führt dieselbe Operation, aber nur auf einem Integer-Wert aus.
   CVTPS2PI (Convert Packed Single-Precision Floating-Point to Packed Integer) transformiert die Gleitpunktzahlen an den beiden unteren Positionen eines 128-bit-Registers in vorzeichenbehaftete 32-bit-Integers und packt sie in ein MMX-Register. Ist das Ergebnis der Konvertierung keine ganze Zahl, so wird es zu einer solchen gerundet. CVTTPS2PI (Convert Truncate Packed Single-Precision Floating-Point to Packed Integer) hingegen schneidet - bei sonst identischer Funktion - in diesem Fall das Ergebnis zu einer ganzen Zahl ab. CVTSS2SI (Convert Scalar Single-Precision Floating-Point to Scalar Integer) und CVTTSS2DI (Convert Truncate Scalar Single-Precision Floating-Point to Scalar Integer) führen dieselben Operationen, aber eingeschränkt auf eine einzige Zahl aus.
   Die Befehle UNPCKHPS und UNPCKLPS (Unpack High/Low Packed Single-Precision) führen dieselben Operationen aus, wie die MMX-Befehle PUNPCKHWD bzw. PUNPCKLWD, jedoch mit gepackten Gleitpunktzahlen.

5. Transferbefehle

   Der Befehl MOV[A,U]PS transportiert gepackte 128-bit-Daten (16 byte) zwischen den Registern der Multimedia-Einheit oder zwischen Register und Hauptspeicher. Der Befehl MOVAPS verlangt dabei, daß Daten im Speicher an 16-byte-Grenzen ausgerichtet sind und erzeugt anderenfalls einen Trap. Der Befehl MOVUPS kann diese Daten an beliebigen Adressen ansprechen. MOVSS entspricht dem Befehl MOVUPS, arbeitet jedoch nur auf einem einzigen "skalaren" 32-bit-Wert.
   Die Befehle MOV[H,L]PS transportieren eine 64-bit-Zahl (zwei Gleitpunktzahlen) zwischen dem Speicher und einem Register; dabei selektiert die Angabe 'H' die oberen beiden, 'L' die unteren beiden Positionen des Registers. MOV[HL,LH]PS schränken diese Operationen auf Registerinhalte ein. MOVHLPS transportiert die obere Hälfte des Quellregisters in die untere des Zielregisters, MOVLHPS die untere Hälfte des Quellregisters in die obere des Zielregisters. Die jeweils nicht selektierten Registerhälften bleiben unverändert.
   MOVMSKPS ermittelt die Vorzeichen der vier Gleitpunktzahlen des Operanden und schreibt sie als 4-bit-Wert in ein allgemeines Register des Prozessors.
   Der Befehl SHUFPS wirkt auf zwei gepackten Gleitpunktoperanden derart, daß er von beiden Operanden jeweils zwei Gleitpunktzahlen herausnimmt und diese zu einem 128-bit-Operanden zusammenpackt. Dabei werden die Zahlen des 1. Operanden in die unteren Positionen, die des 2. In die oberen Positionen gesetzt. Der Befehl PSWAPD der AMD-Prozessoren wirkt - wie bereits gesagt - nur auf gepackten 64-bit-Operanden und vertauscht in ihnen die beiden 32-bit-Zahlen.
   Durch den Befehl PREFETCH ist es möglich, vorausschauend einem Datenblock aus dem Hauptspeicher zu laden und ihn in einem schnellen Cache-Speicher abzulegen (Data Prefetching). Dadurch kann ein nachfolgender Zugriff auf diese Daten erheblich beschleunigt werden, da er nicht mehr auf den langsamen Hauptspeicher durchgeführt werden muß.
   In modernen Mikroprozessoren, wie sie im Verlauf der Vorlesung noch ausführlich beschrieben werden, können (Schreib-)Befehle außerhalb der vom Programm vorgegebenen Reihenfolge durchgeführt und beendet werden. Diese Umordnung der Reihenfolge kann jedoch bei Befehlen, die in einem logischen Zusammenhang stehen, zu ungewünschten Ergebnissen führen. Der Befehl SFENCE verhindert in diesem Fall die Beendigung der Schreibbefehle in einer falschen Reihenfolge, indem neuere Schreibbefehle solange angehalten werden, bis die vorhergehenden beendet wurden.

6. Steuerbefehle (State Management Instructions)

   Durch die Befehle STMXCSR, LDMXCSR (Store/Load Multimedia-Extension Control and Status Register) können die Inhalte von Steuer- und Statusregister der Multimedia-GP-Einheit im Speicher abgelegt bzw. von dort geladen werden. Der Befehl FXSAVE legt - zur Vorbereitung eines Prozeßwechsels - den Gesamtzustand der Gleitpunkt-Einheit, der Multimedia-GP-Einheit und der MMX-Einheit im Speicher ab, der Befehl FXRSTOR restauriert den Zustand dieser Rechenwerke aus dem Speicher. Dabei ist der Gesamtzustand der Einheiten durch den Zustand aller Steuer- und Statusregister (Environment) sowie die Inhalte der Datenregister gegeben.

Zum Abschluß dieses Abschnitts wollen wir in einer weiteren Fallstudie zeigen, wie einfach der Befehlssatz eines RISC-Prozessors sein kann. Dazu haben wir uns den RISC II ausgesucht, dessen Befehlsformate wir bereits in Abschnitt 3.2.2 behandelt hatten. Die Befehlssätze heutiger RISC-Prozessoren sind jedoch wesentlich umfangreicher und liegen der Komplexität nach zwischen dem Befehlssatz des RISC II und den in diesem Abschnitt beschriebenen Befehlssätzen typischer PC-Prozessoren.

Fallstudie 3.2-4: Der Befehlssatz des RISC II
Der Befehlssatz des RISC II ist in Tabelle 3.2-21 dargestellt. Er besitzt 39 Befehle und unterscheidet nur die einfachen Datentypen/-Formate: Byte (B), 16-bit-Kurzwort (short - H), 32-bit-Langwort (long - W), jeweils als vorzeichenlose (unsigned - U) oder vorzeichenbehaftete (signed - S) ganze Zahlen. Beim Laden eines vorzeichenbehafteten Bytes oder eines Wortes wird der Wert in die unteren Positionen eines der 32-bit-Register des Prozessors geschrieben, und die "freibleibenden" Bits werden vorzeichenrichtig aufgefüllt, also bei negativen Zahlen durch '1', bei positiven durch '0'. Lade- und Speicherbefehle sowie Sprünge und Unterprogrammaufrufe können absolut oder relativ (relative) ausgeführt werden. Im 1. Fall wird im Befehl eine absolute Adresse angegeben, im 2. Fall nur ein Offset zu der aktuellen Adresse im Programmzähler (Program Counter - PC). Auffällig ist, daß der Befehlssatz nicht einmal einen NOP-Befehl enthält. Dieser kann jedoch durch den Additionsbefehl "ADD R0,R0,R0" nachgebildet werden, denn ein Schreibbefehl auf das Nur-Lese-Register R0, das die Konstante 0 enthält, hat keine Auswirkungen. Neben der Darstellung im Assemblercode finden Sie in der Tabelle eine kurze textuelle und symbolische Beschreibung der ausgeführten Operation. Wir wollen hier nicht näher auf die einzelnen Befehle eingehen und überlassen Ihnen die Interpretation als Selbsttestaufgabe. Dazu soll Ihnen die der Tabelle folgende Legende dienen. Beachten Sie dabei bitte, daß der Arbeitsspeicher "byte-orientiert" ist. Daher bedeutet die Addition der Zahl 4 zu einer Adresse, daß das auf die berechnete Adresse folgende 32-Bit-Doppelwort (4 Bytes) angesprochen wird. Der Registerspeicher des RISC II wird in überlappende Registerbänke konstanter Länge eingeteilt und - wie in Fallstudie 2.6-4 beschrieben - verwaltet. Daher finden Sie auch Befehle, die die Auswahl eines Registerfensters (Register Window) bewirken. Legende zur Tabelle 3.2-21
A1: | W,HU,HS,BU,BS - Datenlängen und Datentypen beim Lesebefehl
A2: | W,S,B - Datenlängen und Datentypen beim Schreibbefehl
W: | Long: 32-bit-Doppelwort,
H: | Short: 16-bit-Wort, vorzeichenbehaftet oder vorzeichenlos (signed / unsigned)
B: | Byte: 8-bit-Datum, vorzeichenbehaftet oder vorzeichenlos (signed / unsigned)
RD: | Zielregister (Destination Register),
S: | je nach Adr.-Art Adresse oder Inhalt eines Quellregisters bzw. 13-bit-Offset / unmittelbares Datum,
Ri, Rj: | Register,
Y: | 19-bit-Offset / unmittelbares Datum,
M[EA]: | durch die effektive Adresse EA selektierte Speicherzelle,
CC: | Bedingung für bedingte Befehlsausführung (Condition Code),
CWP: | Zeiger auf aktuelle Registerbank (Current Window Pointer),
PSW: | Zustandsregister (Processor Status Word), enthält die Flags und die Zeiger CWP und SWP
PC: | Programmzähler, der auf den aktuell ausgeführten Befehl zeigt
LPC: | Programmzähler, der auf den gerade beendeten Befehl zeigt (Last PC)
NPC: | Programmzähler, der auf den nächsten Befehls zeigt (Next PC)

Tabelle 3.2-21: Der Befehlssatz des RISC-II-Prozessors

Befehl | Assemblerbefehl | Operation
| Arithmetisch/logische Operationen
Integer Add | ADD | Ri,S,RD | RD : = Ri + S
Add with Carry | ADDC | Ri,S,RD | RD := Ri + S + C
Integer Subtract | SUB | Ri,S,RD | RD := Ri - S
Subtract with Carry | SUBC | Ri,S,RD | RD := Ri - S - C
Integer Subtract Reverse | SUBI | Ri,S,RD | RD := S - Ri
Subtract Reverse w. Carry | SUBCI | Ri,S,RD | RD := S - Ri - C
Logical AND | AND | Ri,S,RD | RD := Ri Ù S
Logical OR | OR | Ri,S,RD | RD := Ri Ú S
Logical Exclusive | EOR | Ri,S,RD | RD := Ri ¹ S
Shift Left | SLL | Ri,S,RD | RD := Ri um S Bits nach links verschieben
Shift Right Logical | SRL | Ri,S,RD | RD:=Ri um S Bits logisch nach rechts v.
Shift Right Arithmetic | SRA | Ri,S,RD | RD:=Ri um S Bits arithmetisch nach rechts verschieben
| LOAD/STORE-Befehle
Load | LDX[A1] | (Ri)S,RD | RD := M[Ri+S]
Load Relative | LDR[A1] | Y,RD | RD := M[PC+Y]
Store | STX[A2] | Ri,(Rj)S | M[Rj+S] := Ri
Store Relative | STR[A2] | Ri,Y | M[PC+Y] := Ri
| Verzweigungsbefehle, Unterprogrammaufrufe, Rücksprünge
Conditional Jump | JMPX | CC,(Ri)S | PC := Ri + S
Conditional Relativ Jump | JMPR | CC,Y | PC := PC + Y
Call and Change Window | CALLX | RD,(Ri)S | RD:=PC+4, PC:=Ri+S, CWP:=CWP-1
Call Relative and Change Window | CALLR | RD,Y | RD:=PC+4, PC:=PC+Y, CWP:=CWP-1
Return and Change Window | RET | CC,(Ri)S | PC := Ri + S, CWP := CWP + 1
Call an Interrupt | CALLI | RD | RD := LPC + 4, CWP := CWP - 1
Return from Interrupt | RETI | CC,(Ri)S | NPC := Ri + S + 4, CWP := CWP + 1
| Systembefehle
Load Immediate Highto Restart Delayed Jump | LDHI | RD,Y | RD[Bits 31-13] := Y, RD[Bits 12-0] := 0
Load Last PC | GETLPC | RD | RD := LPC
Load Status Word | GETPSW | RD | RD := PSW
Set Status Word | PUTPSW | Ri | PSW

| Inhaltsverzeichnis
|  | Übersicht Kapitel 3
3.1 Datentypen und Datenformat |  | 3.3 Adressierungsarten