You are currently viewing JASm Coding – Beispielprogramme 1 (Sprung, Addition, Multiplikation , Ausgabe und Funktion)

JASm Coding – Beispielprogramme 1 (Sprung, Addition, Multiplikation , Ausgabe und Funktion)

Prozeduren und Funktionen (Makros)

Eine Prozedur (Funktion) repräsentiert zur Laufzeit wiederverwendbaren Code, der parametrisiert werden kann. Da JASm “nur” globale Variablen kennt, muss die Übergabe von Werten geschickt gehandhabt werden.

Das nachfolgende Beispiel nutzt nun mehrfach den Algorithmus für die Addition (s. o.) ab der Adresse Add. Zur Übergabe der Parameter werden reservierte Speicheradressen verwendet, die hier zur besseren Übersicht mit Add_, also dem “Namen” der Funktion beginnen.

Innerhalb der Funktion müssen die “eigenen” Variablen geordnet wieder initialisiert werden, daher erfolgen einige Rücksetzungen z. B. SUB @Add_tmp @Add_tmp, da andernfalls bei erneutem Aufruf der Funktion diese Zellen bereits mit undefinierten Werten belegt sind. Auch kann nicht ausgeschlossen werden, dass von außerhalb der Funktion diese Zellen manipuliert wurden, da es keinerlei Einschränkungen auf den Speicherbereich gibt.

Für den Aufruf der Funktion bei Add werden im ersten Schritt die erforderlichen Parameter in die Speicherzellen der Funktion übertragen. In diesem speziellen Fall (Addition) nutzen wir die Tatsache, dass die Summe zweier Werte (a+b) der Negation der Summe der negierten Werte -(-a-b) entspricht. Auf diese Weise erspart man sich ein paar Schritte zur Vorzeichenkonvertierung.

Als nächstes muss die Rücksprungadresse hinterlegt werden, damit nach Ausführen der Funktion das Programm an der vorgesehenen Stelle fortgesetzt werden kann. Dies kann nur durch die unmittelbare Manipulation der Rücksprungadresse des JA Befehls in der Funktion erfolgen. Zu Beginn dieses Programms ist die Adresse mit 0 definiert, beim zweiten Aufruf muss die Adresse (Add_ret) wie auch die Speicherzelle tmp auf jeden Fall gezielt auf Null gesetzt werden.

          @Start                # Initialisierung des Programmzeigers
Step:     -3                    # Schrittweite des Programmzeigers

REM Variablen

a1:       10                    # Wert für a1, hier: 10
b1:       5                     # Wert für b1, hier: 5
c1:       0                     # Wert für c1, initialisiert mit 0, wird 15
a2:       7                     # Wert für a2, hier: 7
b2:       3                     # Wert für b2, hier: 3
c2:       0                     # Wert für c2, initialisiert mit 0, wird 10
tmp:      0                     # Puffer für Negationen
ret1:     @return1              # Rücksprungadresse für den ersten Aufruf
ret2:     @return2              # Rücksprungadresse für den zweiten Aufruf

Start:

REM erste Addition c1=a1+b1 veranlassen, 1. Funktionsaufruf

          SUB @Add_a @a1        # Wert für a1 an die Funktion übertragen
          SUB @Add_b @b1        # Wert für b1 an die Funktion übertragen
          SUB @tmp @ret1        # Rücksprungadresse negieren
          SUB @Add_ret @tmp     # negierte Rücksprungadresse übertragen
          JA 0 @Add             # “Funktionsaufruf”
return1:                        # Ziel für den Rücksprung aus der Funkt.
          SUB @c1 @Add_res      # Ergebnis der Funktion abrufen

REM zweite Addition c2=a2+b2 veranlassen, 2. Funktionsaufruf

          SUB @Add_a @a2
          SUB @Add_b @b2
          SUB @tmp @tmp         # Puffer wieder initialisieren
          SUB @tmp @ret2
          SUB @Add_ret @Add_ret # Speicherzelle für Rücksprung löschen
          SUB @Add_ret @tmp
          JA 0 @Add
return2:
          SUB @c2 @Add_res

          SUB 0 0               # Programm beenden

REM Additionsfunktion Add

Add_a:    0                     # lokale Variable für a
Add_b:    0                     # lokale Variable für b
Add_tmp:  0                     # lokaler Puffer für Negation
Add_res:  0                     # Speicher für Rückgabe des Ergebnisses

Add:      SUB @Add_res @Add_res # Ergebnisspeicher zurücksetzen
          SUB @Add_tmp @Add_tmp # Zwischenpuffer zurücksetzen

          SUB @Add_tmp @Add_a   # tmp = -a
          SUB @Add_tmp @Add_b   # tmp = tmp - b = -a - b = -(a + b)
          SUB @Add_res @Add_tmp # res = -tmp = a + b

          SUB @Add_a @Add_a     # Aufräumen, Speicher initialisieren
          SUB @Add_b @Add_b     # für spätere Aufrufe
          JA 0 Add_ret:0        # Zurück zur aufrufenden Stelle

Die Ausführung dieses Programms erfordert insgesamt 31 Schritte. Die Ergebnisse befinden sich danach in den Speicherzellen 4 (@c1) und 7 (@c2).

Makro

Unter Verwendung von Makros sieht der Code – ergänzt um eine Ergebnisausgabe – dann wie folgt aus:

                @Start                          # Initialisierung des Programmzeigers
Step:           -3                              # Schrittweite des Programmzeigers

REM Variablen

a1:             10                              # Wert für a1, hier: 10
b1:             5                               # Wert für b1, hier: 5
c1:             0                               # Wert für c1, initialisiert mit 0, wird 15
a2:             7                               # Wert für a2, hier: 7
b2:             3                               # Wert für b2, hier: 3
c2:             0                               # Wert für c2, initialisiert mit 0, wird 10

                INC ADD                         # An dieser Stelle wird der Code der Addition
                                                # eingefügt

tmp:            0                               # Puffer für Negationen
ret1:           @return1                        # Rücksprungadresse für den ersten Aufruf
ret2:           @return2                        # Rücksprungadresse für den zweiten Aufruf

Start:

REM erste Addition c1=a1+b1 veranlassen, 1. Funktionsaufruf

                SUB @ADD_a @a1                  # Wert für a1 an die Funktion übertragen
                SUB @ADD_b @b1                  # Wert für b1 an die Funktion übertragen
                SUB @tmp @ret1                  # Rücksprungadresse negieren
                SUB @ADD_return @ADD_return     # Speicherzelle für Rücksprung löschen
                SUB @ADD_return @tmp            # negierte Rücksprungadresse übertragen
                JA  0 @ADD                      # “Funktionsaufruf”
return1:                                        # Ziel für den Rücksprung aus der Funktion
                SUB @c1 @ADD_result             # Ergebnis der Funktion abrufen
                SUB -1 @ADD_result              # Ergebnis der Berechnung ausgeben

REM zweite Addition c2=a2+b2 veranlassen, 2. Funktionsaufruf

                SUB @ADD_a @a2
                SUB @ADD_b @b2
                SUB @tmp @tmp                   # Puffer wieder initialisieren
                SUB @tmp @ret2
                SUB @ADD_return @ADD_return     # Speicherzelle für Rücksprung löschen
                SUB @ADD_return @tmp
                JA  0 @ADD
return2:                                        # Ziel für den Rücksprung aus der Funktion
                SUB @c2 @ADD_result             # Ergebnis der Funktion abrufen
                SUB -1 @ADD_result              # Ergebnis der Berechnung ausgeben

                INC EXIT                        # An dieser Stelle wird der Code SUB 0 0 eingefügt

Hierbei werden zwei Makros referenziert: ADD und EXIT.

EXIT ist definiert als SUB 0 0

ADD hingegen ist etwas umfangreicher:

ADD:            SUB @ADD_tmp @ADD_tmp          # lokalen Speicher initialisieren
                SUB @ADD_result @ADD_result    # lokalen Ergebnisspeicher initialisieren
                SUB @ADD_tmp @ADD_a            # tmp = -a
                SUB @ADD_a @ADD_a              # Eingangsgröße a nach Gebrauch initialisieren
                SUB @ADD_tmp @ADD_b            # tmp -= b
                SUB @ADD_b @ADD_b              # Eingangsgröße b nach Gebrauch initialisieren
                SUB @ADD_result @ADD_tmp       # result = -tmp = a+b
                JA  0 ADD_return:0             # Rücksprung zur "aufrufenden" Stelle
ADD_a:          0                              # Eingangsgröße a
ADD_b:          0                              # Eingangsgröße b
ADD_tmp:        0                              # lokale Hilfsvariable
ADD_result:     0                              # Ergebnis der Berechnung a+b

Und weiter?

Die hier gezeigten Beispiele für JASm Code zeigen bereits, dass üblicherweise einfache Aufgaben in JASm abgebildet werden können, allerdings eine nicht unerhebliche Komplexität mit sich bringen. Eine einfache Addition von zwei Werten benötigt 6 Codezeilen – in herkömmlichen Programmiersprachen, selbst Assembler ist dies mit einer einzigen Anweisung zu realisieren.

Bis zu diesem Zeitpunkt war JASm hier nur reine Theorie, wenngleich auch schon eine Umsetzung in PHP existiert. Im nächsten Beitrag wird eine JavaScript Implementierung des Compilers, bzw. Interpreters präsentiert, sodass die JASm Programme auch zum Leben erweckt werden können.

Inhalt

Schreibe einen Kommentar

Nutze dieses Kommentarfeld um deine Meinung oder Ergänzung zu diesem Beitrag kundzutun. Verhalte dich bitte respektvoll und höflich! Kommentare werden vor der Veröffentlichung in der Regel moderiert und bei Verstößen gegen geltendes Recht, die guten Sitten, fehlendem Bezug oder missbräuchlicher Verwendung nicht freigegeben oder gelöscht.
Über die Angabe deines Namens, deiner E-Mail Adresse und deiner Webseite freuen wir uns, doch diese Felder sind optional. Deine E-Mail Adresse wird dabei zu keinem Zeitpunkt veröffentlicht.

Um mit dem Betreiber dieser Seite nicht-öffentlich in Kontakt zu treten, nutze die Möglichkeiten im Impressum.