Gemischte - Pascal und Assembler - Programme

 

Im allgemeinen kann ein Programm aus, in verschiedenen Programmirsprachen geschriebenen Modulen entstehen. So kann jeder Modul in einer, den Erforderungen entsprechenden Sprache geschrieben werden. Zum Beispiel, ein Modul, der Operationen auf einer niedriegen Ebene braucht, könnte in Assembler geschrieben werden, und der Rest des Programmes in Pascal.

 

Damit die, in verschiedenen Sprachen geschriebenen Modulen zusammengefügt werden können, muß man einige Konventionen behalten, so dass die Modulen sich miteinander "verstehen" können.

 

 

         Turbo Pascal Konventionen

 

1. Zusammenfügung der Modulen

Das Hauptprogramm muß immer in Pascal geschrieben werden. Die Modulen können Pascal Units oder Assembler Modulen sein.

Die Assembler Module werden geschrieben und übersetzt (es werden .obj Objektdateien erzeugt). Um die ausführbare Programm zu erstellen, wird ins Hauptprogramm oder in ein Pascal Unit die Direktieve {$L Modulname.obj} geschrieben.

 

Die, in Assembler geschriebene Module werden die folgenden enthalten:

 

- ein Segment namens _TEXT, das die Befehle enthalten wird

- ein Segment namens _DATA, das die globale Variablen enthalten wird; wenn man

  keine globale Variablen braucht, kann dises Segment fehlen

 

2. Aufruf der Prozeduren

Für eine, in Assembler geschriebene Prozedur, die vom Pascal Programm gerufen wird,

muß man folgendes tun:

 

- im Pascal Programm wird die Prozedur deklariert (als wäre es in Pascal geschrieben) aber statt des Rumpfs (Body) der Prozedur wird das Schlüsselwort "external"

  benutzt.

 

- im Assembler Modul wird ein Label mit dem gleichen Namen deklariert, und dieses Label wird publik gemacht (durch eine "public" Deklaration).

 

- es werden die folgende Direktiven benutzt

assume cs:_TEXT

assume ds:_DATA

 

 

Für eine, in Pascal geschriebene Prozedur die wir vom Assembler Modul rufen möchten, sollen wir es im Assembler Modul mit "extrn" deklarieren.

 

 

3. Globale Variablen

Die Turbo Pascal globale Variablen werden im Datensegment _DATA gespeichert. Die Anfangsadresse dieses Segmentes wird am Anfang des Programmes in ds geladen.

 

Der Wert des ds Registers soll behaltet werden (wenn das Assembler Programm modifiziert es, sollen wir es zurücksetzen).

 

Die, in Pascal deklarierte globale Variablen kann man vom Assembler Modul zugreifen. Dafür werden ihre Namen im Assembler Modul als externe Symbole deklariert ("extrn" Direktive).

 

4. Der Stapel (stack)

Der Stapel ist vom Hauptprogramm initialisiert. Er ist von den Pascal Prozeduren benutzt:

- um die Parameter und die Rücksprungsadresse abgeben un abnehmen.

- um die lokale und temporäre Variablen zu speichern.

 

Die Turbo Pascal Prozeduren benützen den Stapel folgenderweise (siehe das

Bild):

    ------------------

   |      ...         |

   | Lokale Variablen |

   |      ...         |  bp-...

   |------------------|

   |     altes BP     | bp+0     <- BP

   | Rueckkehradresse | bp+2     (*)

   |------------------|

   |      ...         | bp+...

   |    Parameter     |

   |      ...         |

    ------------------

1.   Die Ruferprozedur legt in den Stapel die Parameter für den Aufruf.

2.   Die Ruferprozedur ruft das Unterprogramm durch ein call Befehl auf. Dieser Befehl legt die Rückkehradresse auf die Spitze des Stapels.

3.   Am Anfang der Ausführung der gerufene Prozedur, ist die Spitze des Stapels die, auf dem Bild markierte (*) (die Adresse der Spitze des

      Stapels ist immer im SP Register behalten).

4.   Wenn die gerufene Prozedur anfangt, speichert sie zuerst in den Stapel den Wert von Register BP. Danach kopiert den Wert von SP in Register BP.

5.   Danach addiert die gerufene Prozedur zu den Wert von SP die Anzahl des Oktettes die sie für ihre lokale Variablen braucht, im Stapel wird also

      Platz für die lokale Variablen gemacht. Wer immer den Stapel weiterhin benützen wird, wird neue Objekte in den Stapel legen und wird den,

      für die lokale Variablen besetzten Platz nicht ändern.

6.   Die Adressen der Parameter und die Adressen der lokalen Variablen werden relativ zu den Wert von BP ausgerechnet.

7.   Am Ende der Prozedur wird der Wert von BP ins SP kopiert, also die Spitze des Stapels wir wieder der Ort wo der alte Wert von BP (während Schritt 4)

      gespeichert war, und der, für die lokale Variablen besetzter Platz wird so befreit.

8.   Danach nimmt die gerufene Prozedur von der Spitze des Stapels den Wert vom Register BP.

9.   Zum Schluß gibt die gerufene Prozedur die Kontrolle durch den ret Befehl (die Variante mit Parameter) zum Ruferprogramm zurück, und befreit zugleich

      die Zone wo die Parameter gelegt waren.

 

Das Ruferprogramm legt in den Stapel die Parameter zum abgeben. Die Parameter von Typ byte, shortint, word, integer, char, boolean oder enumeriert, die durch den Wert abgegeben sind, werden direkterweise in den Stapel, auf 2 Oktetten gelegt. Die Parameter von Typ longint oder pointer, die durch den Wert abgegeben sind, werden in den Stapel, auf 4 Oktetten  gelegt.

Für Parameter von anderen Typen, oder für Variablen die durch Referenz abgegeben sind, wird in den Stapel die (far) Adresse des aktuellen Parameter gelegt (Segmentadresse, dann Offsetadresse). Wenn es um ein, durch den Wert abgegebene Parameter geht, wird es die Prozedur lokal kopieren, wenn gebraucht (i.e. wenn es modifiziert wird).

 

Die Parameter sind in den Stapel gelegt in der Ordnung, in der sie sich in der Prozedurdeklaration befinden (der erste Parameter wird zuerst in den Stapel gelegt, also ist der "tiefste", wenn die Prozedur effektiv die Kontrolle bekommt).

 

Ein Beispiel befindet sich in der Dateien HauptP.pas und Summe.asm.

 

Anmerkungen:

-         Um die, vom Hauptprogramm abgegebene Parameter anzugreifen, wird im Register BP die Adresse der Spitze des Stapels kopiert, dann sind alle Parameter relativ zu BP adressiert.

-         Die gerufene Prozedur soll am Ende die Parameter aus dem Stapel löschen.

 

 

                   Integrierte Assembler

 

Turbo Pascal erlaubt das Einschiebsel der, in Assembler geschriebene Teile zwischen der Pascal Instruktionen. Diese Assembler Teile sind durch die Schlüsselwörter asm und end demarkiert. Die Syntax ist ein wenig anders als die "gewöhnliche" Assembler Syntax: z. B. die Komments sind nach Pascal Regeln (zwischen { und }), die Labels sollen mit dem Charakter '@' anfangen,

usw.

 

Es gibt auch einige extra Beschränkungen: wir dürfen die Register cs, ds, ss, bp nicht ändern (oder wenn wie eine von denen ändern, sollen wir den Wert zurücksetzen).

 

Die globale Variablen sind angreifbar, solange wir den Wert von ds nicht verändet haben.

Die lokale Variablen sind angreifbar, solange wir den Wert von bp nicht verändet haben.

 

Für weitere einzelheiten konsultieren Sie das Help des Turbo Pascals.

 

Ein Beispiel befindet sich in der Datei pp1.pas.