Das eBook Angewandte Mikroelektronik wurde von Hans Lohninger zur Unterstützung verschiedener Lehrveranstaltungen geschrieben. Weitere Informationen finden sie hier. |
![]() |
Home ![]() ![]() ![]() ![]() |
||
Siehe auch: Reentrante Unterprogramme | ||
![]() ![]() ![]() ![]() ![]() ![]() ![]() |
||
Parameterübergabe
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
|
||
Home ![]() ![]() ![]() ![]() |