GOSUB

Aus C64-Wiki
Wechseln zu: Navigation, Suche
GOSUB
Format: GOSUB <Zeilennummer>
Parameter
<Zeilennummer>: Zeilennumer des Unterprogramms
Einordnung
Typ: Anweisung
Kontext: Programmstruktur
Aufgabe: Aufruf eines Unterprogramms
Abkürzung: goS
Verwandte Befehle
GOTO, ON, RETURN

Anmerkung: Dieser Artikel beschreibt den BASIC-Befehl GOSUB unter BASIC V2 des Commodore 64.


Der BASIC-Befehl GOSUB springt zur angegebenen Zeilennummer (nur als Zahlenkonstante erlaubt) und arbeitet den dort angeführten Programmteil als Unterprogramm ab. Die Programmstelle des GOSUB-Aufrufs merkt sich der BASIC-Interpreter am BASIC-Stapelspeicher, um später dort wieder fortsetzen zu können. Das Unterprogramm endet sobald der BASIC-Befehl RETURN ausgeführt wird und die Programmabarbeitung setzt beim Programmcode hinter dem aufrufenden GOSUB fort.
Damit wird die Grundidee umgesetzt, Programmteile an unterschiedlichen Stellen des Programms immer wieder verwenden zu können und zu einer entsprechende Ersparnis im Umfang und in der Verbesserung der Übersichtlichkeit, aber auch Wartbarkeit des Programmcodes führt.

Eine Parameterübergabe an das aufgerufene Unterprogramm oder das Zurückliefern von Ergebnissen muss mittels Variablen gelöst werden, über deren Gebrauch sehr sorgfältig Buch geführt werden muss. Es kann sonst zu unerwarteten Nebenwirkungen im Programmablauf kommen, falls Variablen mehrfach verwendet werden.

Es können mit dem BASIC-Befehl GOSUB mehrere Unterprogramme hintereinander (also ineinander verschachtelt) aufgerufen werden, allerdings wird immer das zuletzt aufgerufenen Unterprogramm zuerst beendet. Ein Unterprogramm kann sich auch selbst aufrufen (Rekursion), wobei die Rekursionstiefe bzw. die Anzahl ineinander verschachtelten Aufrufe durch den begrenzten BASIC-Stapelspeicher limitiert ist (siehe Auswertung). Zu viele geöffnete bzw. ineinander verschachtelt Unterprogramme führen zur BASIC-Fehlermeldung ?OUT OF MEMORY ERROR. Das theoretische Limit von 26 Verschachtelungen bewegt sich in der Praxis im Bereich rund um 23, wenn man davon ausgeht, dass im Unterprogramm noch sinnvolle Aktionen durchgeführt werden sollen (welche in der Regel ebenso den BASIC-Stapelspeicher gebrauchen).
Existiert die entsprechende Zeilennummer nicht, so erscheint die BASIC-Fehlermeldung ?UNDEF'D STATEMENT ERROR.

Das Verlassen eines Unterprogramms bewirkt zwangsläufig auch, dass alle dort geöffneten FOR-NEXT-Schleifen beendet werden (und die Verwaltungsinformationen am BASIC-Stapelspeicher korrekt bereinigt werden).


Jeder GOSUB-Aufruf benötigt 5 Bytes auf dem BASIC-Stapelspeicher. Diese setzen sich zusammen aus:

  • Adresse auf den BASIC-Text unmittelbar nach dem GOSUB (2 Bytes)
  • Zeilennummer zur zuvor genannten BASIC-Text-Position gehörend (2 Bytes)
  • GOSUB-Token 141/$8D (1 Byte)

Die Werte werden wie am Stapel üblich ausgehend von hohen in Richtung niedriger Adressen abgelegt.

[Bearbeiten] Beispiele

10 PRINT CHR$(147)
20 SP = 20: ZE = 3: A$ = "Guten Tag !": GOSUB 1000: GOSUB 2000
30 SP = 10: ZE = 3: A$ = "Ich bin der Commdore 64": GOSUB 1000: GOSUB 2000
40 SP = 12: ZE = 6: A$ = "Und wie heissen Sie?": GOSUB 1000
100 END
1000 REM Cursorpositionierung
1010 POKE 211,SP :POKE 214, ZE: SYS 58640 : PRINT A$
1020 RETURN
2000 REM Warteschleife
2010 FOR X=0 TO 1500: NEXT X
2020 RETURN

[Bearbeiten] Rekursion

10  REM - DAS RAHMENPROGRAMM
100 INPUT "FAKTORIELLENBERECHNUNG: N=";FA
110 GOSUB 1000
120 PRINT " FAKTORIELLE VON ";FA;"=";FR
130 GOTO 100
1000 REM UNTERPROGRAMM FAKT(FA) -> FR - VERWENDET: I
1010 FR=1: I=1           : REM INITIALISIERUNG
1020 IF I>FA THEN RETURN : REM ABBRUCHBEDINGUNG
1030 FR=FR*I             : REM EIN BERECHNUNGSSCHRITT
1040 I=I+1
1050 GOSUB 1020          : REM REKURSION!
1060 RETURN

Im Grunde kompakter und effizienter mit einer FOR-NEXT-Schleife lösbar, aber hier wird demonstrativ der mathematischen Definition der entsprechenden Funktion (etwas holprig) genüge getan.
Maximaler Eingabewert ist 22, ohne dass der Fehler ?OUT OF MEMORY erscheint.

[Bearbeiten] Experimentelles

Die maximale Anzahl der Verschachtelungen: (oder "Wieviele GOSUB-Aufrufe verträgt der BASIC-Stapel?")

10 GOTO 30
20 READ A     : REM ANZAHL DER GOSUB AUFRUFE
30 GOSUB 20
40 END
50 DATA 1,2,3,4,5,6,7,8,9,10,11,12,13
60 DATA 14,15,16,17,18,19,20,21,22,23
70 DATA 24,25,26,27,28,29,30,31,32,33

Testlauf:

RUN
?OUT OF MEMORY  ERROR IN 30
READY.
PRINT A
 26
 
READY.

Die Konstruktion mit READ-DATA ist eine Methode der Zählung, die den BASIC-Stapelspeicher nicht zusätzlich belastet. Etwaige Schleifenvariablen oder Ausgaben via PRINT würden eine Nutzung des BASIC-Stapelspeichers wegen der Berechnung des jeweiligen Ausdrucks in den Parametern bewirken. Der Überlauf des BASIC-Stapelspeichers träte nämlich dann 2 GOSUB-Aufrufe früher ein.


In anderen Sprachen