1
[DE] Axe Parser Programmierung / [GER] Axe Tutorial auf Deutsch (Wer Lust hat kann mitschreiben)
« on: September 09, 2016, 06:32:59 pm »
Hallo Leute,
Ich habe vor einiger Zeit angefangen ein Axe Tutorial auf Deutsch zu schreiben. Keine kurze Helpfile sondern ein schön ausführliches Tutorial bei dem man wenn möglich bei einmaligem Durchlesen schon Axe lernt ^^
Leider habe ich selbst wenig Ahnung von Axe und schreibe nur auf was mit Hayleia, Sorunome, c4ooo, DarkestEx und viele andere beibringen. Außerdem habe ich auch nicht besonders viel Zeit wodurch ich ewig zum schreiben brauche. Daher habe ich gedacht es könnten ja einfach alle mitschreiben die Lust haben ^^
Hier ist was ich bisher habe, es fehlen noch viele Kapitel (und nir ein paar davon sind vollständig)
Ich hoffe es ist nicht zu schlecht geschrieben xD
Änderungsvorschläge, weitere Kapitel oder was auch immer bitte einfach in die Replies, ich update dann den originalen Post
(Diesen Post gibt es auf CodeWalrus und auf Omnimaga aber ich trage die Ergebnisse zusammen. Es ist also egal wo ihr antwortet)
ACHTUNG: Um Schäden an deinem Taschenrechner zu vermeiden, probiere bitte NIEMALS irgendwelche Codestücke aus, dabei handelt es sich nur um Anschauungs-Beispiele die NICHT ausgeführt werden dürfen! Am Ende jedes Kapitels findest du ungefährliche Beispiele zum Ausprobieren, die in GRÜN markiert sind!
In diesem Kapitle lernst du, Axe zu verwenden und die ersten Grundlagen.
Dieses Kapitel gibt einen Überblick über effzientes Arbeiten mit Variablen
In diesem Kapitel bekommst du eine Einführung in Schleifen und Bedingungen in Axe
In diesem Kapitle lernst du, wie du den Hauptspeicher (RAM) deines Taschenrechners verwenden kannst, um weitere Variablen speichern zu können.
In diesem Kapitel lernst du, wie du eigene Variablen erstellen und selbst benennen kannst.
Ich habe vor einiger Zeit angefangen ein Axe Tutorial auf Deutsch zu schreiben. Keine kurze Helpfile sondern ein schön ausführliches Tutorial bei dem man wenn möglich bei einmaligem Durchlesen schon Axe lernt ^^
Leider habe ich selbst wenig Ahnung von Axe und schreibe nur auf was mit Hayleia, Sorunome, c4ooo, DarkestEx und viele andere beibringen. Außerdem habe ich auch nicht besonders viel Zeit wodurch ich ewig zum schreiben brauche. Daher habe ich gedacht es könnten ja einfach alle mitschreiben die Lust haben ^^
Hier ist was ich bisher habe, es fehlen noch viele Kapitel (und nir ein paar davon sind vollständig)
Ich hoffe es ist nicht zu schlecht geschrieben xD
Änderungsvorschläge, weitere Kapitel oder was auch immer bitte einfach in die Replies, ich update dann den originalen Post
(Diesen Post gibt es auf CodeWalrus und auf Omnimaga aber ich trage die Ergebnisse zusammen. Es ist also egal wo ihr antwortet)
ACHTUNG: Um Schäden an deinem Taschenrechner zu vermeiden, probiere bitte NIEMALS irgendwelche Codestücke aus, dabei handelt es sich nur um Anschauungs-Beispiele die NICHT ausgeführt werden dürfen! Am Ende jedes Kapitels findest du ungefährliche Beispiele zum Ausprobieren, die in GRÜN markiert sind!
In diesem Kapitle lernst du, Axe zu verwenden und die ersten Grundlagen.
Spoiler For Axe Grundlagen:
Um ein Axe-Programm zu schreiben, muss zuerst das Programm als Axe-source gekennzeichnet und ein Name angegeben werden. Diesen Namen erhält dann dein Programm nach dem Kompillieren. Dazu schreibst du in die erste Zeile deines Programms zuerst einen Punkt und anschließend einen Namen. Dieser Name muss alphanumerisch sein (Groß- und Kleinbuchstaben plus Zahlen) und muss mit einem Großbuchstabe beginnen.
Hier ein Beispiel:
Viele der Befehle aus TI-Basic wurden in Axe übernommen oder nur erweitert. Einige wenige wurden aber auch durch eigene Axe-befehle ersetzt. Öffnest du also Menüs wie MATH oder PRGM werden dir einige neue Befehle auffallen. Dies gilt aber naturlich nur in Programmen, die als Axe-source gekennzeichnet sind. Außerhalb solcher Programme solltes du durch Axe keinerlei Änderungen bemerken.
Ein erstes Beispiel für übernommene und veränderte Befehle in Axe ist dieser Code:
Hier ein Beispielcode zum Ausprobieren:
Hier ein Beispiel:
Code: [Select]
PRGM:POKESRC1
:.Pokemon1
:
:1->X
Viele der Befehle aus TI-Basic wurden in Axe übernommen oder nur erweitert. Einige wenige wurden aber auch durch eigene Axe-befehle ersetzt. Öffnest du also Menüs wie MATH oder PRGM werden dir einige neue Befehle auffallen. Dies gilt aber naturlich nur in Programmen, die als Axe-source gekennzeichnet sind. Außerhalb solcher Programme solltes du durch Axe keinerlei Änderungen bemerken.
Ein erstes Beispiel für übernommene und veränderte Befehle in Axe ist dieser Code:
Code: [Select]
PRGM:POKESRC1
:.Pokemon1
:
:1->X
:ClrHome
:Output(1,3,X)
Eine Kurze Erklärung: Wie auch in TI-Basic wird beim Befehl Output( zuerst die Zeile und dann die Spalte angegeben. Dieser Befehl wurde als übernommen, genauso der Befehl ClrHome, der zuerst den Bildschirminhalt für uns löscht. Allerdings wird dieser Code nicht die Zahl 1 sondern einige unlesbare Zeichen ausspucken. Das liegt daran, dass Axe nicht standardmäßig Zahlen als Zahlen anzeigt. (ALS WAS DANN???) Um X als normale Dezimalzahl anzuzeigen, musst du also >Dec anhängen (du findest >Dec im MATH Menü). Dieser Befehl wandelt normalerweise Brüche in Kommazahlen um - Axe hat diesen Befehl verändert und verwendet ihn zur Kennzeichnung was angezeigt werden soll. Alternativ kannst du auch >Char anhängen. Das Signalisiert dem Compiler dass du hier das Zeichen nummer 1 (da 1->X) aus dem Zeichensatz des Taschenrechners angezeigt werden soll. Für X=1 solltest du hier ein kursives n bekommen.Hier ein Beispielcode zum Ausprobieren:
Code: [Select]
PRGM:POKESRC1
:.Pokemon1
:
:35->X
:ClrHome
:Output(15,3,X>Char
:Output(11,4,X>Dec
Zur Information: Der Befehl Output( schreibt zahlen automatisch rechtsbündig in einem gedachten 5 Zeichen breiten Feld, daher die 11 und die 15 damit beide Anzeigen rechtsbündig sind. Dieses Kapitel gibt einen Überblick über effzientes Arbeiten mit Variablen
Spoiler For "Arbeiten mit Variablen":
Axe ist weit mehr als TI-Basic auf geschwindigkeit optimiert und bietet daher auch viel mehr Möglichkeiten. Um dein Axe-Programm auch schön schnell ausführen zu können solltest du aber darauf achten, es auch so effizient wie möglich zu schreiben. Dadurch gewinnst du sowohl Speicherplatz als auch Geschwindigkeit.
Schon die Zuweisung einfacher Variaben lässt sich in Axe optimieren:
Dies ist ein Beispiel für einen Langsamen, nicht optimierten Code:
Damit spart man natürlich nicht besonders viel Zeit, es wird aber immer empfohlen möglichst optimierten Axe code zu schreiben da der Unterschied bei größeren Programmen doch deutlich bemerkbar ist.
Zwar ist es eher üblich zuerst die Grundlagen und danach erst die Optimierungen zu lernen, allerdings ist es sehr zu empfehlen von anfang an optimierten Code zu schreiben. Dadurch gewöhnst du dir einen besseren Programmierstil an und du sparst deutlich Zeit da es viel länger dauert einen schlechten Code zu modifizieren.
Schon die Zuweisung einfacher Variaben lässt sich in Axe optimieren:
Dies ist ein Beispiel für einen Langsamen, nicht optimierten Code:
Code: [Select]
2->A:2->B:1->X
1->Y
1->Z[code]
Dieser lässt sich so modifizieren:
[code]2->A->B
1->X->Y->Z
Spoiler For Was der Prozessor hier macht:
Im Codebeispiel 1 (dem nicht optimierten Code) macht der Prozessor folgendes:
Im Codebeispiel 2 (dem optimierten Code) macht der Prozessor folgendes:
Code: [Select]
"2" --> Zwischenspeicher
Zwischenspeicher --> Variable-A
"2" --> Zwischenspeicher
Zwischenspeicher --> Variable-B
"1" --> Zwischenspeicher
Zwischenspeicher --> Variable-X
"1" --> Zwischenspeicher
Zwischenspeicher --> Variable-Y
"1" --> Zwischenspeicher
Zwischenspeicher --> Variable-Z
Im Codebeispiel 2 (dem optimierten Code) macht der Prozessor folgendes:
Code: [Select]
"2" --> Zwischenspeicher
Zwischenspeicher --> Variable-A
Zwischenspeicher --> Variable-B
"1" --> Zwischenspeicher
Zwischenspeicher --> Variable-X
Zwischenspeicher --> Variable-Y
Zwischenspeicher --> Variable-Z
Damit spart man natürlich nicht besonders viel Zeit, es wird aber immer empfohlen möglichst optimierten Axe code zu schreiben da der Unterschied bei größeren Programmen doch deutlich bemerkbar ist.
Zwar ist es eher üblich zuerst die Grundlagen und danach erst die Optimierungen zu lernen, allerdings ist es sehr zu empfehlen von anfang an optimierten Code zu schreiben. Dadurch gewöhnst du dir einen besseren Programmierstil an und du sparst deutlich Zeit da es viel länger dauert einen schlechten Code zu modifizieren.
In diesem Kapitel bekommst du eine Einführung in Schleifen und Bedingungen in Axe
Spoiler For Schleifen und Bedingungen:
Wie auch TI-Basic verwendet Axe If für einfache Bedingungen sowie For( und While für Schleifen. Deren Verwendung und Schreibweise ist aber teilweise anders als du es vielleicht schon von TI-Basic gewohnt bist:
Der IF-Befehl
Anders als in TI-Basic ist eine If-Abfrage IMMER mit einem End zu beenden. Dabei ist es egal ob der dadurch ausgeführte Befehlsblock nur einen einzigen Befehl oder 1000 Befehle umfasst. Dafür ist aber auch kein Then mehr nötig:
Natürlich lässt sich auch ein Else einbauen und das If verschachteln:
Natürlich lassen sich auch Bedingungen in Axe noch stark optimieren (wenn auch diesmal auf Kosten der Lesbarkeit, aber man gewöhnt sich daran).
*HIER DEN SCHEIß MIT A=B?1,2:->X UND SO ERKLÄREN
Der IF-Befehl
Anders als in TI-Basic ist eine If-Abfrage IMMER mit einem End zu beenden. Dabei ist es egal ob der dadurch ausgeführte Befehlsblock nur einen einzigen Befehl oder 1000 Befehle umfasst. Dafür ist aber auch kein Then mehr nötig:
Code: [Select]
If x=2
3->X
5->Z
End
Hier im Beispiel werden sowohl 3->X als auch 5->Z nur ausgeführt, wenn die if-Bedingung zutrifft. TI-Basic hätte den if-Block nach dem ersten Befehl (5->Z) beendet.Natürlich lässt sich auch ein Else einbauen und das If verschachteln:
Code: [Select]
If X=2
3->X
4->Y
Else
4->X
if Y=5
10->Z
End
End
Hier wurde der Code zur besseren Lesbarkeit mit Leerzeichen eingerückt. Anders als TI-Basic erlaubt Axe es, deinen Code tatsächlich so zu schreiben. Beim Kompillieren werden diese Leerzeichen ignoriert, sie haben also keinen Einfluss auf das spätere Programm und dienen nur der besseren Lesbarkeit. Sie zu verwenden lohnt sich leider wegen der geringen Bildschirmbreite des Taschenrechners nur selten.Natürlich lassen sich auch Bedingungen in Axe noch stark optimieren (wenn auch diesmal auf Kosten der Lesbarkeit, aber man gewöhnt sich daran).
*HIER DEN SCHEIß MIT A=B?1,2:->X UND SO ERKLÄREN
In diesem Kapitle lernst du, wie du den Hauptspeicher (RAM) deines Taschenrechners verwenden kannst, um weitere Variablen speichern zu können.
Spoiler For Die verwendung des Hauptspeichers:
In diesem Kapitel ist es besonders wichtig, nur Codes auszuführen, die mit Grün markiert sind! Experimente mit dem Hauptspeicher können echte Schäden verursachen. Wenn du dir nicht sicher bist, wende dich an die Community, damit sie deine Codes prüft, bevor du etwas ausprobierst.
Axe bietet die Möglichkeit, Variablen direkt in den RAM zu speichern. Das hat den Vorteil dass dir die Variablennamen nicht ausgehen (A-Z reichen oft nicht). Das geht folgendermaßen:
In Axe wird mit {X} der inhalt des Bytes X zurückgegeben.
X bezieht sich dabei auf die Hauptspeicheradresse, also die Adresse im RAM.
Hier ein Beispiel - Dies überschreibt den Inhalt des ersten Bytes (Adresse 0) mit X, speichert also X an der ersten Position im RAM:
Eine 1 Byte lange Zahl kann nur 2^8 Werte haben, also eine zahl zwischen 0 und 255.
Das ist natürlich viel zu wenig, also verwendet Axe standartmäßig 2 Byte pro Variable.
Damit kommt man auf 2^16 Werte, also einen Zahlenbereich von 0 bis 65.535
Das heißt dieser Code wird uns ein Problem bereiten:
Die Zahl 300 ist binär: 0000-0001-0010-1100, also 256+32+8+4
Sie besteht also aus 2 Bytes: 0000-0001 und 0010-1100. Versucht man nun die 300 wie oben abzuspeichern, kann nur das erste Byte tatsächlich abgespeichert werden. Das heißt aus der 300 wird 0000-0001, also die Zahl 1.
Um dieses Problem zu umgehen, wird {0}^r verwendet.
(Du findest das r unter 2nd -> APPS)
Durch das Anhängen des r signalisierst du dem Compiler, dass hier nicht nur das eine Byte {0} angesprochen werden soll, sondern zwei Bytes auf einmal:
Um eine 1Byte lange Zahl zu speichern (0-255) reicht also ein Byte, für den Rest müssen 2 Bytes verwendet werden:
Wenn ihr nicht allzuviel Wert auf Speicherplatz legt aber auf nummer sicher gehen wollt, verwendet also einfach nur gerade Hauptspeicheradressen und arbeitet immer mit Bytepaaren.
Genauso wie sich einzelne Bytes im Hauptspeicher einfach setzen lassen, kann man sie natürlich auch wieder abrufen:
Übrigens: Zwar ist L1 nur eine einzelne Position, aber man spricht trotzdem davon, Variablen IN L1 abzuspeichern wenn sie in diesem Bereich gespeichert werden. Der einachkeit halber übernehmen wir das auch.
Das heißt wenn du mehr Speicherplatz für Variablen brauchst, stehen dir {L1+0}^r bis {L1+256}^r zur freien Verfügung.
Theoretisch kannst du das selbe übrigens auch mit L2, L3, L4, L5 und L6 machen, davon wird aber abgeraten da diese schon von Axe verwendet werden:
Wenn du z.B: Interrupts in deinem Programm verwendest, werden diese in L2 gespeichert. Und L6 entspricht dem Bildschirm, d.h. Veränderst du etwas in L6 ist das als würdest du etwas auf dem Bildschirm anzeigen lassen. Solange dir L1 reicht vermeide es also, L2, L3, L4, L5 oder L6 zu verwenden. Und wenn dir doch der Platz ausgeht, dann frage besser einen Profi bevor du es einfach ausprobierst.
Zusätzlich besteht noch die Möglichkeit, einzelne Nibbel anzusteuern (ein Nibbel ist eine 4Bit-Einheit, so wie ein Byte eine 8Bit-Einheit ist. Und jep, die heißen wirklich so!) Das machst du so:
Mit nib{ (du findest den Befehl unter [Math] -> NUM -> 3) wählst du eine 4Bit-Einheit aus. Wie auch Bytes werden die Nibbel mit Adressen angesteuert. ABER: Die Adressen der Nibbel sind auf 4 statt auf 8 Bit ausgelegt. Das heißt die Adresse "4" bezieht sich NICHT auf das 4. Byte sondern auf das 4. Nibbel, sprich das 2. Byte. Das heißt du musst die gewünschte Adress im Hauptspeicher zuerst Verdoppeln (zB das hundertste Nibbel liegt im 50sten Byte, daher die Verdoppelung damit die Adressen sich auch hier auf Bytes beziehen).
Nehmen wir einmal an das erste Byte in L1 wäre 1010-1111 und wir rufen nib{L1*2} auf, dann wird uns 1010 zurückgegeben.
Rufen wir nib{L1*2+1} auf, dann wird uns 1111 zurückgegeben.
Um das vierte Byte in L1 aufzurufen schreiben wir also nib{L1+3*2} und nib{L1+3*2+1} auf. (Beachte dass das +3 ebenfalls verdoppelt werden muss da es sich um Byte-Angaben handelt)
Es besteht aber auch die Möglichkeit, zwei Nibbels (also ein Byte) auf einmal abzufragen. Hier dazu ien Beispiel:
A = 1010 Hier wird einfach das erste Nibbel aus dem Byte L1+4 abgefragt
B = 1111 Hier wird das zweite Nibbel aus dem selben Byte abgefragt
C = 1111-1010 Hier werden 2 Nibbel abgefragt, beginnend mit dem ersten Nibbel im Byte L1+4. Die Reihenfolge der Nibbel wird dabei standardmäßig vertauscht.
D = 0000-1111 Auch hier werden 2 Nibbel abgefragt, das zweite Nibbel in L1+4 und das nächste, also das erste Nibbel in L1+5. Auch hier die vertauschte Reihenfolge.
E = 1010-1111 Hier werden wieder beide Nibbel aus L1+4 abgefragt - aber die Nibbels explizit getauscht. Das heißt ihre Reihenfolge stimmt wieder.
F = 1111-0000 Hier werden wieder das zweite Nibbel aus L1+4 und das erste aus L1+5 angefragt - in richtiger Reihenfolge.
Wichtig: Beim Arbeiten mit Nibbeln darfst du NIEMALS vergessen, die Adresse zu verdoppeln da du ansonsten einen anderen Bereich im Speicher ansprichst und eventuell Schäden an deinem Taschenrechner entstehen!
*HIER NOCH WEITERSCHREIBEN*
Axe bietet die Möglichkeit, Variablen direkt in den RAM zu speichern. Das hat den Vorteil dass dir die Variablennamen nicht ausgehen (A-Z reichen oft nicht). Das geht folgendermaßen:
In Axe wird mit {X} der inhalt des Bytes X zurückgegeben.
X bezieht sich dabei auf die Hauptspeicheradresse, also die Adresse im RAM.
Hier ein Beispiel - Dies überschreibt den Inhalt des ersten Bytes (Adresse 0) mit X, speichert also X an der ersten Position im RAM:
Code: [Select]
X->{0}
(Na gut, eigentlich die erste Position im Flash-speicher, da dieser bei $0000 beginnt und der RAM erst bei $8000 (Hexadezimale Angaben - also 32.768 in Dezimal).)Eine 1 Byte lange Zahl kann nur 2^8 Werte haben, also eine zahl zwischen 0 und 255.
Das ist natürlich viel zu wenig, also verwendet Axe standartmäßig 2 Byte pro Variable.
Damit kommt man auf 2^16 Werte, also einen Zahlenbereich von 0 bis 65.535
Das heißt dieser Code wird uns ein Problem bereiten:
Code: [Select]
300->{0}
Ein kurze Erklärung:Die Zahl 300 ist binär: 0000-0001-0010-1100, also 256+32+8+4
Sie besteht also aus 2 Bytes: 0000-0001 und 0010-1100. Versucht man nun die 300 wie oben abzuspeichern, kann nur das erste Byte tatsächlich abgespeichert werden. Das heißt aus der 300 wird 0000-0001, also die Zahl 1.
Um dieses Problem zu umgehen, wird {0}^r verwendet.
(Du findest das r unter 2nd -> APPS)
Durch das Anhängen des r signalisierst du dem Compiler, dass hier nicht nur das eine Byte {0} angesprochen werden soll, sondern zwei Bytes auf einmal:
Code: [Select]
300->{0}^r
Das erste Byte (die Adresse 0) bekommt hier 0000-0001 zugewiesen und das zweite Byte (die Adresse 1) bekommt 0010-1100.Um eine 1Byte lange Zahl zu speichern (0-255) reicht also ein Byte, für den Rest müssen 2 Bytes verwendet werden:
Code: [Select]
5->{0}
42->{1}
83->{2}
9001->{3}^r
500->{5}^r
Hierbei ist zu beachten dass {4} bereits durch 9001->{3}^r mitverwendet wird.Wenn ihr nicht allzuviel Wert auf Speicherplatz legt aber auf nummer sicher gehen wollt, verwendet also einfach nur gerade Hauptspeicheradressen und arbeitet immer mit Bytepaaren.
Code: [Select]
5->{0}^r
42->{2}^r
83->{4}^r
9001->{6}^r
500->{8}^r
Genauso wie sich einzelne Bytes im Hauptspeicher einfach setzen lassen, kann man sie natürlich auch wieder abrufen:
Code: [Select]
555->{16}^r
{16}^r+7->A[code]
Nun ist es natürlich keine gute Idee, irgendwelche Adressen im RAM (oder Flash) einfach zu überschreiben. Du riskierst damit ernsthafte Schäden an deinem Taschenrechner!
Aber natürlich bietet Axe dir eine sichere Möglichkeit diese Technik einzusetzen: [b]L1[/b]
Anders als in Basic ist [b]L1[/b] in Axe keine Liste, sondern eine einfache Adresse im Hauptspeicher. Du denkst die L1 am besten als konstante variable mit irgendeiner komischen Zahl als wert. Das hört sich jetzt komisch an, ist aber eigentlich ganz einfach:
[b]L1[/b] markiert eine Position im Hauptspeicher, an der unbenutzter Speicher zur Verfügung steht, wodurch du also auch nichts kaputt machen kannst :)
Wenn du jetzt das erste Bytepaar von L1 ansteuern willst, machst du das so:
[code]9000->{L1}^r
{L1}^r+1->A
Natürlich stellt L1 dir auch ordentlich Platz zur verfügung: Du kannst die nächsten 256 Bytes, die nach L1 kommen, problemlos verwenden.Übrigens: Zwar ist L1 nur eine einzelne Position, aber man spricht trotzdem davon, Variablen IN L1 abzuspeichern wenn sie in diesem Bereich gespeichert werden. Der einachkeit halber übernehmen wir das auch.
Das heißt wenn du mehr Speicherplatz für Variablen brauchst, stehen dir {L1+0}^r bis {L1+256}^r zur freien Verfügung.
Theoretisch kannst du das selbe übrigens auch mit L2, L3, L4, L5 und L6 machen, davon wird aber abgeraten da diese schon von Axe verwendet werden:
Wenn du z.B: Interrupts in deinem Programm verwendest, werden diese in L2 gespeichert. Und L6 entspricht dem Bildschirm, d.h. Veränderst du etwas in L6 ist das als würdest du etwas auf dem Bildschirm anzeigen lassen. Solange dir L1 reicht vermeide es also, L2, L3, L4, L5 oder L6 zu verwenden. Und wenn dir doch der Platz ausgeht, dann frage besser einen Profi bevor du es einfach ausprobierst.
Spoiler For Codebeispiele zum ausprobieren:
Zusätzlich besteht noch die Möglichkeit, einzelne Nibbel anzusteuern (ein Nibbel ist eine 4Bit-Einheit, so wie ein Byte eine 8Bit-Einheit ist. Und jep, die heißen wirklich so!) Das machst du so:
Mit nib{ (du findest den Befehl unter [Math] -> NUM -> 3) wählst du eine 4Bit-Einheit aus. Wie auch Bytes werden die Nibbel mit Adressen angesteuert. ABER: Die Adressen der Nibbel sind auf 4 statt auf 8 Bit ausgelegt. Das heißt die Adresse "4" bezieht sich NICHT auf das 4. Byte sondern auf das 4. Nibbel, sprich das 2. Byte. Das heißt du musst die gewünschte Adress im Hauptspeicher zuerst Verdoppeln (zB das hundertste Nibbel liegt im 50sten Byte, daher die Verdoppelung damit die Adressen sich auch hier auf Bytes beziehen).
Nehmen wir einmal an das erste Byte in L1 wäre 1010-1111 und wir rufen nib{L1*2} auf, dann wird uns 1010 zurückgegeben.
Rufen wir nib{L1*2+1} auf, dann wird uns 1111 zurückgegeben.
Um das vierte Byte in L1 aufzurufen schreiben wir also nib{L1+3*2} und nib{L1+3*2+1} auf. (Beachte dass das +3 ebenfalls verdoppelt werden muss da es sich um Byte-Angaben handelt)
Es besteht aber auch die Möglichkeit, zwei Nibbels (also ein Byte) auf einmal abzufragen. Hier dazu ien Beispiel:
Code: [Select]
nib{L1+4*2}->A
nib{L1+4*2+1}->B
nib{L1+4*2}^r->C
nib{L1+4*2+1}^r->D
nib{L1+4*2}^r^r->E
nib{L1+4*2+1}^r^r->F
Nehmen wir an, dass L1+4 und L1+5 diesen Inhalt haben: 1010-1111 0000-0110, dann bewirkt der Code folgendes:A = 1010 Hier wird einfach das erste Nibbel aus dem Byte L1+4 abgefragt
B = 1111 Hier wird das zweite Nibbel aus dem selben Byte abgefragt
C = 1111-1010 Hier werden 2 Nibbel abgefragt, beginnend mit dem ersten Nibbel im Byte L1+4. Die Reihenfolge der Nibbel wird dabei standardmäßig vertauscht.
D = 0000-1111 Auch hier werden 2 Nibbel abgefragt, das zweite Nibbel in L1+4 und das nächste, also das erste Nibbel in L1+5. Auch hier die vertauschte Reihenfolge.
E = 1010-1111 Hier werden wieder beide Nibbel aus L1+4 abgefragt - aber die Nibbels explizit getauscht. Das heißt ihre Reihenfolge stimmt wieder.
F = 1111-0000 Hier werden wieder das zweite Nibbel aus L1+4 und das erste aus L1+5 angefragt - in richtiger Reihenfolge.
Wichtig: Beim Arbeiten mit Nibbeln darfst du NIEMALS vergessen, die Adresse zu verdoppeln da du ansonsten einen anderen Bereich im Speicher ansprichst und eventuell Schäden an deinem Taschenrechner entstehen!
*HIER NOCH WEITERSCHREIBEN*
In diesem Kapitel lernst du, wie du eigene Variablen erstellen und selbst benennen kannst.
Spoiler For Benutzerdefinierte Variablen:
Nachdem du im letzten Kapitel gelernt hast L1 zu verwenden wird dir sicher aufgefallen sein, dass es sehr nervig ist immer {L1+14}^r anstatt X zu schreiben. Und dann soll man sich auchnoch merken an welcher Stelle in L1 was gespeichert ist? Igitt! Zum Glück bietet die Axe auch hier wieder eine Möglichkeit dies zu umgehen:
Du kannst in Axe eigene Variablen erstellen, indem du ihnen einen Namen und eine Adresse im Hauptspeicher zuordnest. Ein Beispiel davon sieht so aus:
Zuerst wird 16 der neuen Variable Alter zugewiesen. Da Variablen standardmäßig 2 Bytes verwenden, werden somit [b{16} und {17}[/b] beziehugnsweiße wird {16}^r dem Namen Alter zugewiesen. Das ° vor dem Namen signalisiert dem Compiler, dass hier 16 eine Hauptspeicheradresse ist und Alter eine neue Variablenbezeichnung.
Das ° findest du unter 2ND -> APPS und du darfst es hierbei niemals vergessen!
Sobald die Variable deklariert ist (sie also "erstellt" ist), kannst du sie problemlos verwenden, ohne dass du das ° dazuschreiben musst. Dieses brauchst du nur einmalig zum Erstellen der Variable.
Übrigens darf der Variablenname bis zu 16 Zeichen lang sein und aus Groß- und Klienbuchstaben bestehen. Achte aber darauf dass deine Variablennamen mit einem Großbuchstaben anfangen! Außerdem darfst du bestehende Variablenwie z.B. X oder Y nicht überschreiben.
Auch hier hilt natürlich, dass es schlecht, ist irgendwelche RAM-Regionen zu verändern, auch hier solltest du also auf L1 zurückgreifen. Das geht so:
Ein kurzes Beispiel für einen Typischen solchen Fehler:
Der Wert 1768 wird {L1}^r also {L1} und {L1+2} zusammen zugeordnet. (0000-0110 und 1110-1000). Die Deklaration von °Kuchen verwendet jetzt aber den WERT von L1 anstatt der Adresse. Da hier nur {L1} verwendet wurde, ist dieser Wert 6 (0000-0110). Die Variable Kuchen wird also den Bytes 6 und 7 zugeordnet - irgendwo mitten im Flash-speicher. Richtig wäre gewesen:
Bitte beachte dass bei solchen Variablendeklarationen IMMER 2 Byte verwendet werden. Wenn du also in deinem Programm diese Technik verwendest, wird dringend empfohlen, NUR 2-Byte Variablen im Hauptspeicher zu verwenden. Sich überlappende Variablen im Hauptspeicher gehören zu den am schwierigsten zu findenden Fehlern überhaut - das willst du nicht
Du kannst in Axe eigene Variablen erstellen, indem du ihnen einen Namen und eine Adresse im Hauptspeicher zuordnest. Ein Beispiel davon sieht so aus:
Code: [Select]
16->°Alter
20->Alter
Hier eine erklärung was der Code macht:Zuerst wird 16 der neuen Variable Alter zugewiesen. Da Variablen standardmäßig 2 Bytes verwenden, werden somit [b{16} und {17}[/b] beziehugnsweiße wird {16}^r dem Namen Alter zugewiesen. Das ° vor dem Namen signalisiert dem Compiler, dass hier 16 eine Hauptspeicheradresse ist und Alter eine neue Variablenbezeichnung.
Das ° findest du unter 2ND -> APPS und du darfst es hierbei niemals vergessen!
Sobald die Variable deklariert ist (sie also "erstellt" ist), kannst du sie problemlos verwenden, ohne dass du das ° dazuschreiben musst. Dieses brauchst du nur einmalig zum Erstellen der Variable.
Übrigens darf der Variablenname bis zu 16 Zeichen lang sein und aus Groß- und Klienbuchstaben bestehen. Achte aber darauf dass deine Variablennamen mit einem Großbuchstaben anfangen! Außerdem darfst du bestehende Variablenwie z.B. X oder Y nicht überschreiben.
Auch hier hilt natürlich, dass es schlecht, ist irgendwelche RAM-Regionen zu verändern, auch hier solltest du also auf L1 zurückgreifen. Das geht so:
Code: [Select]
L1+0->°XPosition
Wichtig: Hier wird nur L1+... geschrieben, aber nicht {L1+...} da hier die Adresse benötigt wird, nicht der ausgelesene Inhalt dieser Adresse.Ein kurzes Beispiel für einen Typischen solchen Fehler:
Spoiler For "Fehler":
Code: [Select]
1768->{L1}^r
{L1}->°Kuchen
1700->Kuchen
Was hier passiert ist folgendes:Der Wert 1768 wird {L1}^r also {L1} und {L1+2} zusammen zugeordnet. (0000-0110 und 1110-1000). Die Deklaration von °Kuchen verwendet jetzt aber den WERT von L1 anstatt der Adresse. Da hier nur {L1} verwendet wurde, ist dieser Wert 6 (0000-0110). Die Variable Kuchen wird also den Bytes 6 und 7 zugeordnet - irgendwo mitten im Flash-speicher. Richtig wäre gewesen:
Code: [Select]
1768->{L1}^r
L1->°Kuchen
1700->Kuchen
Hierbei wird die Adresse von L1 verwendet und somit wird der zuor zugewiesene Wert von 1768 jetzt mit 1700 überschrieben.Bitte beachte dass bei solchen Variablendeklarationen IMMER 2 Byte verwendet werden. Wenn du also in deinem Programm diese Technik verwendest, wird dringend empfohlen, NUR 2-Byte Variablen im Hauptspeicher zu verwenden. Sich überlappende Variablen im Hauptspeicher gehören zu den am schwierigsten zu findenden Fehlern überhaut - das willst du nicht