Assembler

Aus C64-Wiki
Wechseln zu: Navigation, Suche

Assembler ist eine Programmiersprache, welche eine für Menschen bessere, lesbare Repräsentation der Maschinensprache ist. Als Assembler wird nicht nur die Sprache selbst, sondern auch ihr Compiler benannt. Übersetzt der Compiler ein Assembler-Programm in die Maschinensprache, so nennt man den Vorgang "assemblieren". Den umgekehrten Vorgang nennt man "disassemblieren".

Allgemeines[Bearbeiten]

Jede Prozessorarchitektur (z.B. x86, RISC) hat einen anderen Befehlssatz und folglich auch eine andere Assembler-Sprache, dennoch weisen diese untereinander immer Ähnlichkeiten auf. Maschinenbefehle und ihre Operanden bestehen aus Zahlen, die wiederum als Binärcode im Speicher vorliegen. Da pure Zahlenreihen für den Menschen nur schwer lesbar sind, fasst man diese Opcodes in Kürzel (Mnemonics - gesprochen Niemonix) zusammen.

Ein Assembler übersetzt diese Mnemonics in Bitmuster bzw. eine Folge von Bytes, bestehend aus Opcodes und Daten.

Neben Assembler als separaten Compiler, finden sich auch einfachere Formen in Maschinensprachemonitore oder sogenannte "Inline-Assembler" bei Hochsprachen, etwa einem C-Compiler, wo mit speziellen Instruktionen Assembler-Befehle direkt in die Hochsprachensyntax eingebettet werden können. Der Assembler kann sogar als Teil der Compiler-Suite für den letzten Schritt, die Erzeugung des Maschinencodes verantwortlich sein.

C64-Assembler[Bearbeiten]

Ein Beispiel zu Assembler beim C64:

*=$C000    ; Startadresse des Programms = $C000 = 49152
LDA #$00   ; 0 in den Akku laden
STA $D020  ; Akku nach Register $20 des VIC schreiben (Farbe des Bildschirmrands)
... 

... im Speicher des C64 würde es nun so aussehen:

Adresse  Opcode + Operand(en)

C000     A9 00      ; "C000" ist die Speicheradresse, 
                    ; "A9" ist der Opcode für LDA, 
                    ; "00" ist der Operand
C002     8D 20 D0   ; "C002" ist die Speicheradresse, 
                    ; "8D" ist der Opcode für STA, 
                    ; "20" und "D0" sind die Operanden (low/high-Reihenfolge)
...

... und als Binärcode ab $C000 (die Leerzeichen dienen nur optischen Gruppierung in 8er-Gruppen)

10101001 00000000 10001101 00100000 11010000

Makros[Bearbeiten]

Manche Assembler für den C64 (z.B. Hypra-Ass, INPUT ASS, TurboAssembler oder Crossassembler ACME ) übersetzen nicht nur die Mnemonics, sondern bieten auch die Möglichkeit Makros anzulegen an. Diese werden dann Makro-Assembler genannt. Makros lassen sich vereinfacht als Aneinanderreihung von Befehlen ersetzt durch einen Platzhalter zusammenfassen, was insbesondere beim relativ begrenzten Befehlsumfang des MOS 6510 den Quelltext des Programms stark verkürzen kann und es auch lesbarer macht. Beispiel: Will man einen 16-Bit-Wert im Speicher kopieren, ist das ausgeschrieben z.B.

LDA $xxxx
STA $yyyy
LDA $xxxx+1
STA $yyyy+1

Diese Sequenz ist nicht sonderlich lesbar. Mit einem entsprechend definierten Makro wird daraus z.B.

move16 $xxxx,$yyyy

Zu beachten ist, dass Makros Tipparbeit einsparen, aber das fertig übersetzte Programm natürlich genauso viel Speicher braucht. Außerdem müssen bei Makros stets auf Nebenwirkungen geachtet werden. Im Beispiel zuvor muss z.B. bei der Benutzung von "move16" klar sein, dass dabei der Akku überschrieben wird, was bei den Einzelbefehlen noch offensichtlich war.
Die Verwendung von Makros verhindert aber eventuell auch das Erkennen von Umständen für besondere Optimierungen hinsichtlich Code-Ausführungsgeschwindigkeit und Code-Länge. Beispielsweise kann ein Makro damit enden, dass das Y-Register stets 0 ist und so dem anschließenden Code ermöglichen den Akku "billig" mit TYA zu löschen oder das explizite Löschen des Y-Registers unterbleiben kann.

Charakteristiken[Bearbeiten]

Bezogen auf C64-Assembler.

Vorteile[Bearbeiten]

  • sehr maschinennah, das heißt:
    • Eine taktgenaue Ansteuerung z.B. des VIC ist möglich (spezielle Grafikeffekte möglich).
    • Volle Kontrolle über alles Bereiche der Speicherbelegung (unter BASIC ist z.B. kein lesender Zugriff auf das RAM unter dem BASIC-ROM möglich).
    • Die Nutzung und Kontrolle von Interrupts ist möglich.
  • sehr schnell:
    • Bei etwa drei Takten pro Befehl und 1 MHz Takt werden ca. 300.000 Assembler-Befehle pro Sekunde verarbeitet - BASIC schafft nur wenige dutzend bis hunderte Befehle pro Sekunde.
  • geringer Speicherverbrauch (kompakter Programmcode und effiziente, bit-genaue Datenstrukturen)

Nachteile[Bearbeiten]

  • schwer zu erlernen:
    • Die Bedeutung der einzelnen Opcodes ist einfach, aber jeder einzelne Befehl bewirkt noch nicht viel.
    • Eine Aufgabe kann auf viele verschiedene Arten formuliert werden. Oft gebrauchte Codesequenzen und effiziente Codierungstechniken (z.B. 16-Bit-Operationen) müssen als Erfahrung aufgebaut werden.
    • Ein recht tiefes Wissen über die Hardware und residenter Systemsoftware (BASIC-ROM und KERNAL-ROM) ist sinnvoll.
    • Die Entwicklung und das Testen von Programmen ist mühsam und fehlerträchtig, da bereits kleinste logische Fehler im Programmablauf fatale Abstürze hervorrufen können. Bei Nutzung von Emulatoren relativiert sich das allerdings etwas.
  • hoher Programmieraufwand:
    • Aus Sicht des MOS 6510 gibt es nur Speicherstellen und Bytes.
      • Komplexere Datentypen, wie Strings und Fließkommazahlen sind der CPU fremd und müssen irgendwie in Bytes dargestellt und verarbeitet werden.
      • Ein-/Ausgabe-Konzepte wie "Bildschirminhalt" oder "Diskettenlaufwerk" kennt die CPU nicht; diese Dinge "verstecken" sich hinter (Byte-)Registern einzelner Chips des C64, die wiederum an bestimmten Speicherstellen eingeblendet sind. Ohne Nutzung von BASIC-/KERNAL-Routinen wird in dem Bereich alles zu einer Tortur.
    • Selbst einfache Rechenoperationen sind teilweise nicht trivial, z.B. gibt es beim MOS 6510 keinen Multiplikations- oder Divisions-Opcode. Man muss diese Operationen also aus Addition bzw. Subtraktion und Schiebeoperationen nachbilden oder BASIC-/KERNAL-Routinen dazu benutzen.
    • Schon die Ausgabe einer einzigen Zahl auf dem Bildschirm benötigt viele Einzelbefehle: In BASIC ist es einfach ein PRINT (Zahl), in Assembler muss man entweder die Zahl in Dezimalstellen zerlegen (mangels Division nicht ganz einfach), die einzelnen Ziffern in Bildschirmcode umwandeln und dann in den Bildschirmspeicher schreiben oder die Zahl an die richtige Stelle im Speicher schreiben und eine BASIC-/KERNAL-Routine aufrufen, die vorige Schritte dann ausführt.
  • nicht portabel:
    • Ausführbarkeit: Einfache BASIC-Programme mögen z.B. auf dem C64 und dem VIC-20 laufen, aber kaum ein Assembler-Programm läuft auf beiden Rechnern oder anderen der gleichen Prozessorarchitektur.
    • Wiederverwendbarkeit: Algorithmen in einem Assembler-Dialekt lassen sich nur schwer (erfordert entsprechende Erfahrung) auf Rechnern einer anderen Plattform bzw. eines anderen CPU-Typs übertragen.

Nutzung von Assembler heute[Bearbeiten]

Assembler hat einen hohen Lehrwert und man erlangt nebenbei - zumindest beim C64, bei neueren Rechnern und Betriebssystemen aber nur noch bedingt - tieferes Verständnis für die Arbeitsweise eines Computers. Auch heute wird noch auf bestimmten Plattformen (z.B. im Zusammenhang mit Microcontrollern) in Assembler programmiert, da sich zum Beispiel zeitkritische Probleme so besser lösen lassen als in Hochsprachen. Für die allermeisten Probleme wird man aber bei aktuellen Rechnern auf Hochsprachen zurückgreifen, da Compiler inzwischen sehr gut optimieren und selbst interpretierte Sprachen dank Just-in-time-Kompilierung und anderen Techniken ähnliche Geschwindigkeiten wie reiner Assembler erreichen. Abgesehen vom Geschwindigkeitsaspekt, spielt auch das Erreichen gewisser CPU-Eigenschaften, wie das Ansprechen besonderer Register und Modi eine wesentliche Rolle, was aus einer Hochsprache heraus kaum vorgesehen ist.

Beispiele[Bearbeiten]

Bildschirm komplett schwarz färben ... (SYS 49152)

       *=$C000    ; Startadresse des Programms = $C000 = 49152
       LDA #$00   ; 0 in den Akku laden
       STA $D020  ; Akku nach Register $20 des VIC schreiben (Farbe des Bildschirmrands)
       STA $D021  ; Akku nach Register $21 des VIC schreiben (Farbe des Bildschirmhintergrunds)
       RTS        ; zurück zur aufrufenden Routine

Weblinks & Literatur[Bearbeiten]