Das eBook Angewandte Mikroelektronik wurde von Hans Lohninger zur Unterstützung verschiedener Lehrveranstaltungen geschrieben. Weitere Informationen finden sie hier.


Parameterübergabe

Ein wichtiger Punkt bei der Gestaltung von Unterprogrammen ist die Übergabe von notwendigen Parametern. Dazu stehen im Wesentlichen drei Methoden zur Verfügung: Die Übergabe in Registern, die Übergabe am Stack und die Übergabe durch Speichervariablen. Je nach Zahl und Art der Parameter wird man eine dieser drei Methoden oder eine Kombination davon wählen.

Die Parameterübergabe mit Registern ist die einfachste Methode, sie schränkt jedoch die Zahl der Parameter auf die Zahl der vorhandenen Register ein. Außerdem können im Allgemeinen nur einfache Integer-Parameter übergeben werden. Diese Methode wird meist dann verwendet, wenn man nur wenige Parameter benötigt (z.B. die Zahl der Durchläufe in Verzögerungsschleifen).

Das folgende Beispiel zeigt die Übergabe eines Parameters an ein Unterprogramm mit Hilfe eines Registers. Das Register HL wird mit dem gewünschten Wert geladen und dann das Unterprogramm DELAY aufgerufen. Im Unterprogramm DELAY wird HL solange dekrementiert, bis HL gleich null ist.

;
;           Hauptprogramm
;
            bla         bla
            LD          HL,1000     ;Parameter zur Übergabe
            CALL        DELAY       ;Aufruf der Verzögerung
            bla         bla
;
;           Unterprogramm
;
DELAY:      DEC         HL          ;Parameter dekrementieren
            LD          A,L         ;Überprüfung ob gleich 0
            OR          H
            JR          NZ,DELAY    ;Wiederholung bis HL=0
            RET

Für längere Parameterlisten bzw. für Unterprogramme, die von Compilern verwendet werden, wird man die Parameterübergabe via Stack einsetzen. Dazu werden vor dem Aufruf des Unterprogramms die notwendigen Parameter auf den Stack gelegt und das Unterprogramm holt die Parameter vor seiner eigentlichen Ausführung wieder vom Stack. Dabei gibt es allerdings eine kleine Hürde, die vor allem unter Anfängern immer wieder Verwirrung stiftet. Bei der Übergabe der Parameter via Stack hat man dafür zu sorgen, dass die Rücksprungadresse, die ja ganz zuoberst am Stack liegt, erhalten bleibt und trotzdem der Stack bereinigt wird. Das Unterprogramm muss also zuerst die Rücksprungadresse vom Stack nehmen, diese in einem Register zwischenspeichern, dann die übergebenen Parameter vom Stack holen und dann die Rücksprungadresse wieder auf den Stack schieben.

Dieser Vorgang klingt reichlich kompliziert und kann in der Tat zu schwer durchschaubaren Programmabstürzen führen, wenn durch einen Programmierfehler etwa der Stack nicht vollständig bereinigt wird. Trotz dieses komplizierten Vorgangs ist aber die Parameterübergabe via Stack bei bestimmten Programmen (reentrante und rekursive Programme, siehe unten) die einzig mögliche und sinnvolle.

Das folgende Beispiel zeigt an einem sehr einfachen Aufruf (nur ein Parameter) die Übergabe via Stack. Das Hauptprogramm lädt den gewünschten Parameter auf den Stack und ruft dann das Unterprogramm auf. Das Unterprogramm holt zuerst die durch den Befehl CALL gespeicherte Rücksprungadresse vom Stack. Dabei wird automatisch der Stackpointer inkrementiert, so dass er dann auf den übergebenen Parameter zeigt. Nun wird durch einen speziellen Austauschbefehl der Parameter mit der Rücksprungadresse getauscht, so dass nun die Rücksprungadresse am Stack liegt und der gewünschte Parameter im Register HL geladen ist.

;
;           Hauptprogramm
;
            bla         bla
            LD          HL,1000
            PUSH        HL
            CALL        DELAY
            bla         bla
;
;           Unterprogramm
;
DELAY:      POP         HL          ;Rücksprungadresse nach HL
            EX          (SP),HL     ;Parameter mit Rücksprung-
                                    ;   adresse tauschen
DEL1:       DEC         HL          ;Parameter dekrementieren
            LD          A,L         ;Überprüfung, ob gleich 0
            OR          H
            JR          NZ,DEL1     ;Wiederholung, bis HL=0
            RET

Die dritte Möglichkeit zur Parameterübergabe ist die Übergabe mit Hilfe von Speichervariablen. Diese Möglichkeit sollte man nur einsetzen, wenn große Felder übergeben werden, da sie leicht zu unerwünschten Nebeneffekten führen kann. Muss man an ein Unterprogramm ein Feld mit vielen Elementen übergeben, kann dies bei den anderen Methoden unmöglich sein, weil die Zahl der Register nicht ausreicht bzw. der Platz für den Stack zu klein ist. In diesem Fall übergibt man nicht das Feld selbst, sondern nur eine Zeigervariable, die die Adresse des Feldes enthält. Die Zeigervariable kann wahlweise über den Stack oder in Registern übergeben werden. Falls das Unterprogramm sehr spezielle Aufgaben erfüllt und die zu bearbeitenden Variablen ohnehin fix vereinbart sind, so kann die Übergabe eines Zeigers auch unterbleiben.

Das folgende Beispiel zeigt die Übergabe eines Parameters in einer Speichervariablen. Der gewünschte Wert des Parameters wird zuerst in einer globalen Variablen gespeichert und dann das Unterprogramm aufgerufen. Im Unterprogramm wird nun auf diese Variable zugegriffen und das Register HL mit diesem Wert initialisiert.

;
;           Hauptprogramm
;
            bla         bla
            LD          HL,1000
            LD          (ANYVAR),HL
            CALL        DELAY
            bla         bla
;
;           Unterprogramm
;
DELAY:      LD          HL,(ANYVAR) ;Parameter in HL laden
DEL1:       DEC         HL          ;Parameter dekrementieren
            LD          A,L         ;Überprüfung, ob HL = 0
            OR          H
            JR          NZ,DEL1     ;Wiederholung, bis HL = 0
            RET


Last Update: 2008-05-31