Basic-Zeilen genau betrachtet
Wenn Sie eine Basic-Zeile eingeben und anschließend RETURN drücken, legt der Interpreter die Zeile im Speicher ab. Will man Basic-Zeilen durch ein Maschinenprogramm erzeugen oder in einem Basic-Programm nach bestimmten Befehlen suchen, muß man wissen, wie und wo Basic-Zeilen gespeichert sind.
In den Speicherzellen 43/44 steht die Anfangsadresse des Basic-Speichers. Die Adresse, bei der Basic beginnt, erfahren Sie durch die Abfrage PRINT PEEK(43) + 256 * PEEK(44). Sie erhalten den Wert 2049. Das ist die Adresse, ab der die erste Basic-Zeile vom Interpreter gespeichert wird. Wie Basic-Zeilen im Speicher vorliegen, soll am folgenden Beispielprogramm erläutert werden.
10 Print “PROBE”
300 REM C-64
1200 A$ = “A = A”
50000 END
Bild 1 und 2 zeigen, wie der Interpreter diese vier Basic-Zeilen ab der Adresse 2049 speichert. Die Werte in Klammern sind die Startadressen der einzelnen Basic-Zeilen und dienen nur dem besseren Überblick. Alle Werte sind dezimal und hexadezimal angegeben.
Linkpointer | Zeilennummer | Basic-Text | ||||||||||||
(0801) | 0F | 08 | 0A | 00 | 99 | 20 | 22 | 50 | 52 | 4F | 42 | 45 | 22 | 00 |
(2049) | 15 | 8 | 10 | 0 | 153 | 32 | 34 | 80 | 82 | 79 | 66 | 69 | 34 | 0 |
" | P | R | O | B | E | " | ||||||||
(080F) | 1C | 08 | 2C | 01 | 8F | 20 | 43 | 20 | 2D | 20 | 36 | 34 | 00 | |
(2063) | 28 | 8 | 44 | 1 | 143 | 32 | 67 | 32 | 45 | 32 | 54 | 52 | 0 | |
REM | C | — | 6 | 4 | ||||||||||
(081C) | 29 | 08 | B0 | 04 | 41 | 24 | B2 | 22 | 41 | 3D | 41 | 22 | 00 | |
(2076) | 41 | 8 | 176 | 4 | 65 | 36 | 178 | 34 | 65 | 61 | 65 | 34 | 0 | |
A | $ | = | " | A | = | A | " | |||||||
(0829) | 2F | 08 | 50 | C3 | 80 | 00 | ||||||||
(2089) | 47 | 8 | 80 | 195 | 128 | 0 | ||||||||
END | ||||||||||||||
(082F) | ||||||||||||||
(2095) | 0 | 0 |
Die ersten beiden Bytes jeder Zeile heißen Linkpointer oder einfach Verbindungszeiger, manche sprechen auch von Koppeladressen. Der Wert dieser beiden Bytes entspricht immer der Startadresse der nächsten Zeile. Das erste Byte ist das Low- und das zweite das High-Byte der Adresse. In Bild 1 ergeben die ersten 2 Byte der ersten Zeile den Wert 15+8x256 = 2063, also die Adresse, bei der die zweite Zeile beginnt. Der Linkpointer der vierten Zeile (47+8x256) zeigt auf die Speicherstelle 2095. Die beiden Null-Codes in 2095 und 2096 (der Linkpointer der fünften Zeile) signalisieren dem Interpreter das Programmende.
Byte 3 und 4 jeder Zeile ergeben die Zeilennummer der jeweiligen Basic-Zeile. In der ersten Zeile ergeben diese 2 Byte 10 + 0 x 256 = 10.
Im Beispielprogramm steht, nach dem Linkpointer und der Zeilennummer, als fünftes Byte, das Token für PRINT (99). Um Speicherplatz zu sparen und eine schnelle Programmabarbeitung zu erzielen, werden alle Basic-Befehle (PRINT, REM, END,…) in nur 1 Byte übersetzt. Ein 1-Byte-Befehlswort heißt Token. Der Interpreter holt sich die Information, welches Token einem bestimmten Befehlswort entspricht, aus einer Zuordnungstabelle im ROM. Die Tabelle beginnt ab Adresse 41118 ($A090). Bild 3 zeigt einen Überblick über alle Basic-Befehle und deren Token. Die Leerstelle nach der Zeilennummer, die nach dem LIST-Befehl am Bildschirm zu sehen ist, wird nicht berücksichtigt. Die Leerstelle zwischen PRINT und dem Anführungszeichen steht als ASCII-Code 32 im sechsten Byte. Auf die gleiche Weise werden das Anführungszeichen, das Wort PROBE und das Schlußzeichen im ASCII-Code gespeichert. Das Beispiel zeigt, daß der Interpreter alle Zeichen, außer Befehlswörtern, im ASCII-Code speichert. Das gilt auch für Befehlswörter in Anführungszeichen (“PRINT”). Diese Unterscheidung können Sie in der dritten Zeile deutlich erkennen. Das erste Gleichheitszeichen stuft der Interpreter als Operator ein (Token 178, $B2), das Gleichheitszeichen in Anführungsstrichen als ASCII-Code 61 ($3D). Eine Aufstellung der ASCII-Codes finden Sie Ihrem Handbuch zum C 64 auf Seite 135.
Befehl | Token | Befehl | Token | Befehl | Token | |||
DEZ | HEX | DEZ | HEX | DEZ | HEX | |||
END | 128 | 80 | CONT | 154 | 9A | SGN | 180 | B4 |
FOR | 129 | 81 | LIST | 155 | 9B | INT | 181 | B5 |
NEXT | 130 | 82 | CLR | 156 | 9C | ABS | 182 | B6 |
DATA | 131 | 83 | CMD | 157 | 9D | USR | 183 | B7 |
INPUT# | 132 | 84 | SYS | 158 | 9E | FRE | 184 | B8 |
INPUT | 133 | 85 | OPEN | 159 | 9F | POS | 185 | B9 |
DIM | 134 | 86 | CLOSE | 160 | A0 | SQR | 186 | BA |
READ | 135 | 87 | GET | 161 | A1 | RND | 187 | BB |
LET | 136 | 88 | NEW | 162 | A2 | LOG | 188 | BC |
GOTO | 137 | 89 | TAB | 163 | A3 | EXP | 189 | BD |
RUN | 138 | 8A | TO | 164 | A4 | COS | 190 | BE |
IF | 139 | 8B | FN | 165 | A5 | SIN | 191 | BF |
REST. | 140 | 8C | SPC | 166 | A6 | TAN | 192 | 00 |
GOSUB | 141 | 8D | THEN | 167 | A7 | ATN | 193 | C1 |
RETURN | 142 | 8E | NOT | 168 | A8 | PEEK | 194 | 02 |
REM | 143 | 8F | STEP | 169 | A9 | LEN | 195 | C3 |
STOP | 144 | 90 | + | 170 | AA | STR$ | 196 | C4 |
ON | 145 | 91 | — | 171 | AB | VAL | 197 | C5 |
WAIT | 146 | 92 | * | 172 | AC | ASC | 198 | C6 |
LOAD | 147 | 93 | / | 173 | AD | CHR$ | 199 | 07 |
SAVE | 148 | 94 | ↑ | 174 | AE | LEFT$ | 200 | C8 |
VERIFY | 149 | 95 | AND | 175 | AF | RIGHT$ | 201 | C9 |
DEF | 150 | 96 | OR | 176 | B0 | MID$ | 202 | CA |
POKE | 151 | 97 | > | 177 | B1 | GO | 203 | CB |
PRINT# | 152 | 98 | = | 178 | B2 | |||
153 | 99 | < | 179 | B3 |
Das Ende jeder Programmzeile ist durch eine Null markiert. Der Interpreter erkennt daran das Zeilenende und nimmt sich die nächste Zeile vor. Enthalten die beiden Bytes für den Linkpointer Null-Codes, ist für den Interpreter das Programm zu Ende. Im Beispiel sind es die Adressen 2095 und 2096 ($082F, $0830).
Mehr Verständnis für den NEW-Befehl
Im Handbuch steht, daß NEW das Programm im Speicher löscht. Das ist nur bedingt richtig, denn der NEW-Befehl löscht nicht das ganze Programm, sondern schreibt nur zwei Null-Codes in die Speicherstellen 2049 ($801) und 2050 ($802). Sie können das mit einem Monitor, zum Beispiel dem SMON, überprüfen. Außerdem werden die Zeiger für Variablenanfang, Feldanfang und Feldende auf die Adresse 2051 gesetzt.
Zum Beweis dieser Aussage sollten Sie einmal das Beispielprogramm eintippen und die folgenden Direktbefehle eingeben.
NEW | |
POKE 2049,15 | |
POKE 2050,8 | Linkpointer |
POKE 45,49 | |
POKE 46,8 | Variablen-Anfang |
POKE 47,49 | |
POKE 48, 8 | Feld-Anfang |
POKE 49,49 | |
POKE 50,8 | Feld-Ende |
LIST |
Die Werte für den ersten Linkpointer und die Variablenzeiger werden mit diesen acht POKE-Befehlen wieder hergestellt. Sie gelten nur für dieses Beispielprogramm. Geben Sie nach NEW eine neue Basic-Zeile ein, dann kann das gelöschte Programm nicht mehr gerettet werden.
Wenn Sie nun am Ende dieses Satzes drei Nullen finden, dann wissen Sie
- der Satz ist zu Ende und
- der Artikel ist zu Ende.
000
(J.Effenberg/hm)