Impressum
< Zeitschleifen Inhalt Interrupts >

Unterprogramme

Aufbau eines Unterprogramms

Ein Unterprogramm beginnt mit einem Label und endet mit ret (=return).
Beispiel:
zeit:
	; Code
	ret

Aufruf eines Unterprogramms

Für den Aufruf eines Unterprogramms existieren zwei Befehle Nahezu jeder Assembler erlaubt die Verwendung von call, welches er je nach Bedarf in ein acall oder lcall adr16 umsetzt.
Bei einem call-Befehl springt der Mikrocontroller in das Unterprogramm, arbeitet es ab und kehrt mit ret direkt hinter den call-Befehl zurück.
Ein jmp-Befehl würde zwar ausreichen um in das Unterprogramm zu springen, allerdings könnte man nicht mehr zum Aufrufer zurückkehren, da dessen Adresse nicht gespeichert wäre.
Da ein Unterprogramm von mehreren beliebigen Stelle im Code aufgerufen werden kann, muss sich der Mikrocontroller die Rücksprungadresse merken. Da ein Unterprogramm wiederum Unterprogramme aufrufen kann reicht ein einziger Speicherplatz für diese Rücksprungadresse nicht aus. Aus diesem Grund wird für die Sicherung der Rücksprungadressen der Stack verwendet.

Der Stack

Ein Stack (im deutchen Kellerspeicher) ist ein Speicher in welchen man Werte speichern kann und diese beim Auslesen in umgekehrter Reihenfolge bekommt. Er verhält sich also wie ein Tellerstapel, das zuletzt abgelegte Teller wird als erstes wieder herausgenommen.
Einen Wert auf den Stack legen nennt man pushen, einen Wert vom Stack nehmen heißt popen. Der Assembler hat hierfür die Befehle push dadr und pop dadr.
Bei einem Unterprogrammaufruf wird die aktuelle Adresse des Programm Counters (PC) auf den Stack gepushed, zuerst das niederwertige und dann das höherwertige Byte des PC. Bei einem ret werden die zwei obersten Werte vom Stack genommen (gepoped) und in den PC geschrieben. Durch diese Änderung des PC kehrt das Programm wieder zum Aufrufer zurück.
Da der Stack eine variable Größe hat merkt sich der Mikrocontroller in dem Stackpointer (SP) an Adresse 081h im SFR die Adresse des letzten Werts des Stacks. Der Stackinhalt (die gespeicherten Werte) werden im RAM abgelegt. Zu Beginn hat der SP den Wert 7. Beim Ablegen auf den Stack wird zuerst der SP erhöht und an der Speicherzelle im RAM, auf welche SP verweist, der Wert gespeichert.
Beim herunternehmen eines Wertes wird genau umgekehrt vorgegangen: Zuerst wird der Wert vom Stack ausgelesen (Adresse aus dem SP) und dann der SP um eins vermindert.

Werte sichern

Ein Unterprogramm soll nur die Werte der Speicherzellen verändern die es muss. Berechnet ein Unterprogramm etwas und legt das Ergebnis an Port 1 ab, so sollte sich außer P1 nichts verändern. Ist ein Unterprogramm nur dazu da um eine gewisse Zeit zu warten, so soll es keine Speicherzelle verändern.
Bei dem Beispiel eines Unterprogramms, welches wartet verändern die Zeitschleifen darin z.B. die Register R0 bis R2. Damit dennoch die Werte der Register vor und nach dem Aufruf des Unterprogramms gleich sind müssen sie gesichert werden. Für dieses Sichern und Wiederherstellen wird der Stack verwendet.
Werte sichern geschieht mit push dadr, das Wiederherstellen am Ende des Unterprogramms mit pop dadr. Hierbei ist darauf zu achten, dass man die Werte in umgekehrter Reihenfolge wiederherstellt in welcher man sie gesichert hat.
Beispiel: Sichern von Werten auf dem Stack
zeit:
	push R3
	push R2
	push R1
	;Zeitschleife
	pop R1
	pop R2
	pop R3
	ret