11. Anlage
 
zurück
11.3.1 Zugriff auf Maschinenbefehle


Bei der Systemprogrammierung und in eingebetteten Anwendungen wird mit Maschinenbefehlen auf Schnittstellen von Hardware-Geräten zugegriffen. Ebenso ist die Ausführung bestimmter Maschinenbefehle notwendig, z. B. zusammengesetzte Operationen im gemeinsam genutzten Speicher (shared memory), wie "Testen-und-Setzen" und "Vergleichen-und-Austauschen" und Befehle für komplizierte Operationen, wie "Übersetze-und-Teste" und optimierte Vektorarithmetik.
Es gibt verschiedene Möglichkeiten, um von einem Ada-Programm auf Maschinenbefehle zuzugreifen:

1. Offenes Einfügen (inline insertion)

Der Verwaltungsaufwand von Unterprogrammen in Assemblersprache ist dort zu hoch, wo die Wirkungsweise eines Befehls (z. B. Teste-und-Setze oder direkte Ein-/Ausgabe) gewünscht ist. Hierfür wird ein offenes (inline) Einfügen von Maschinenbefehlen (maschine code insertion) und vordefinierten Unterprogrammen (intrinsic subprograms) benötigt. Der Übersetzer bietet eine oder auch beide Möglichkeiten.

Einfügen von Maschinenbefehlen (maschine code insertion)

Ada ermöglicht, daß Unterprogramme vollständig aus Beschreibungen von Maschinenbefehlen bestehen. Nur use-Klauseln sind im Vereinbarungsteil erlaubt. Anstelle von Anweisungen enthält der Prozedurrumpf eine Sequenz von qualifizierten Ausdrücken, gefolgt von Semikolons. Jeder qualifizierte Ausdruck enthält ein Verbundaggregat von einem der Maschinenbefehlstypen, die von System.Machine_Code geliefert werden.

Der Prozedurrumpf darf keine Ausnahmebehandler (exception handler) enthalten. Ein Übersetzer kann weitere Einschränkungen auferlegen, zum Beispiel fordern, daß Ausdrücke in einem Verbundagregat statisch sind oder Parameter verbieten.

Das Einfügen von Maschinenbefehlen sollte sparsam und nur für sehr kurze Folgen von Maschinenbefehlen (d. h. fünf bis 10 Befehle) verwendet werden. Wenn eine längere Sequenz von Befehlen festgelegt werden soll, ist es i. a. klarer und weniger beschwerlich, eine Assemblerroutine zu schreiben und sie in ein Ada-Programm zu importieren.


Beispiele

-- 1)
M: Mask;
procedure Setze_Maske;
pragma Inline ( Setze_Maske );

with System.Machine_Code; use System.Machine_Code;
procedure Setze_Maske is
begin
   SI_Format’( Code => SSM, B => M’Base_Reg, D => M’Disp );
   -- Base_Reg und Disp sind implementierungsabhängige Attribute
end Set_Mask;

-- 2)
with System.Machine_Code; use System.Machine_Code;
procedure Besorge_Dienst ( Argument: in Integer; Ergebnis: out Integer ) is
   -- Der Inhalt des Parameters Argument wird dem Register R0
   -- zugewiesen. Der hexadezimale Überwacheraufruf (supervisor call)
   -- 12 veranlaßt die Ausführung eines Betriebssystemdienstes. Das
   -- Ergebnis im Register R1 wird in den Parameter Ergebnis übernommen
begin
   Machine_Instruction’(LOAD,R0,Argument’Offset,Stack_Pointer);
   Machine_Instruction’(SVC,16#12# );
   Machine_Instruction’(STORE,R1,Ergebnis’Offset,Stack_Pointer);
end Besorge_Dienst;


Merke:

Der Inhalt des Bibliothekspakets System.Machine_Code ist implementierungsabhängig. Normalerweise stellt jeder qualifizierte Ausdruck einen Maschinenbefehl oder eine Assemblerdirektive dar. Verbundkomponenten stimmen mit Feldern des Befehls überein. (Auf Maschinen mit verschiedenen Befehlsformaten kann der Operationscode als Diskriminante in einem Verbundtyp mit Varianten dienen.) Das Paket kann auch andere Möglichkeiten bieten, z. B. Aufzählungstypen, deren Werte Operationscodes oder Register benennen. Der Übersetzer kann auch Attribute liefern, die für das Füllen der Befehlsfelder nützlich sind. Solche Attribute liefern für bestimmte Einheiten die Verschiebungen (offsets) von Adressen, auf die besondere Register zeigen.


Vordefinierte Unterprogramme (intrinsic subprogramms)

Ein Aufruf eines vordefinierten Unterprogramms wird offen (inline) in einen oder mehrere Maschinenbefehle übersetzt. Vordefinierte Unterprogramme können für alle Maschinenbefehle vorhanden sein oder nur für den bequemen Zugriff zu besonders häufig verwendeten Operationen oder zu jenen Maschinenoperationen, die besondere Fähigkeiten oder Leistungsstärke bieten.

Beispiele solcher Befehle sind:
  • Unteilbare Lese-Verändere-Schreib-Operationen - z. B. Teste-und-Setze (test and set), Vergleichen-und-Austauschen (compare and swap), Dekrementiere-und-Teste (decrement and test),
    Einreihen/Ausreihen (enqueue/dequeue).
  • Numerische Standardfunktionen - z. B. sin, log.
  • Zeichenkettenmanipulationsoperationen - z. B. Übersetze-und-Teste (translate and test).
  • Vektoroperationen - z. B. vergleiche Vektor gegen Schwellenwerte (thresholds).
  • Direkte Operationen auf Ein-/Ausgängen.
Es muß auf den ganzen Befehlssatz der zugrundeliegenden Maschine zugegriffen werden können.
Dazu gehören auch privilegierte Operationen.
Durch implementierungsabhängige Attribute können Ada-Einheiten als Operanden verwendet werden.

Diese Anlage läßt die Schnittstelle zur Maschinensprache zum großen Teil offen, so daß sie implementierungsabhängig ist.

Durch implementierungsabhängige Attribute können Ada-Einheiten als Operanden in Maschinenbefehlen verwendet werden. Die Werte der Variablen des Ada-Programms können gelesen oder verändert und Ada-Prozeduren aufgerufen werden.
Jedes als exportiert angeführte Ada-Objekt kann von einem Maschinenbefehl oder Assemblerunterprogramm gelesen und verändert werden. Das Pragma "Export" weist den Übersetzer an, Optimierungen auf einem exportierten Objekt nicht durchzuführen. Das Pragma "Export" kann auch verwendet werden, um sicherzustellen, daß die angegebene Einheit einem adressierbaren Ort zugeordnet ist, der vom Bindeprozeß beibehalten wird. Zum Beispiel kann das bedeuten, daß eine
Konstante in Wirklichkeit im Speicher abgelegt werden muß, obwohl sie normalerweise vom Ada-Übersetzer im Zuge der Übersetzung eliminiert wird.


 
zurück
 Index   Ada Tour - Dokumentation  
© 2003 Förderverein Ada Deutschland e.V.