Hallo Besucher, der Thread wurde 6,3k mal aufgerufen und enthält 32 Antworten

letzter Beitrag von Mike am

6502 Assembler Standard und Reference Manual

  • Zitat von detlef

    Deswegen verwende ich auch meinen eigenen Disassembler - eigentlich mehr ein Unassembler, der versucht assemblierbaren Quelltext zu erzeugen.
    Wobei der jetzt nicht versucht, Datenbereiche automatisch zu erkennen. Aber er liest ein Config-File, wo ich die Datenbereiche vorgeben kann.
    Nach mehreren Durchläufen sind die Datenbereiche dann identifiziert (anhand illegaler Opcodes und merkwürdiger Labels).

    Diese Vorgehensweise wird wohl für die von dir genannte "Haupt"-Problemstellung, sprich Rekonstuktion eines Sourcecodes für einen nicht zu verschiebenden (da binär identischen) Objektcode ausreichen.


    Wenn ich mich da dransetze, ist der Source anschließend voll verschiebbar. Und im aktuellen Fall war das Neuzuweisen der verwendeten Datenbereiche gleich noch mal ein nettes Extra - das fällt so eben nur an, wenn man auf eine andere Maschine portiert, welche die Zeropage und den anschließenden OS Workspace anders nutzt.


    Die Trennung von Code und Daten ist da nur der erste Schritt. Das muß man für jeden Objektcode aber ohnehin nur einmal machen und für mich gibt's da zu viele bekannte Fallstricke als daß ich das einem Programm überlasse ... ;)

  • Was die Adressierungsarten anbelangt, so dürften diese (mit Ausnahme des unlogischen "ASL A") weitgehend syntaktisch gleich gekennzeichnet werden:


    Da geht's schon wieder los. :D
    ASL A war aber Standard (weil von MOS vorgegeben). Und wenn ein Assembler das nicht hinkriegt, funktionieren 80% meiner Quelltexte nicht mehr. Da bin ich dann sofort raus.


    Schwierigkeiten gibt es eher bei weiteren Elementen wie ">" und "<" (für höher- bzw. niederwertigen Teil) oder '*' für die aktuelle ORG-Adresse sowie Kennzeichnung von Zeropage- oder Absolutadressen. Diese werden unterschiedlich gehandhabt oder teils nicht unterstützt.

    Mein Assembler erkennt neben *,<,> auch noch H, und L,. Das war AVMAC-Syntax. Ansonsten wird ZP-Adressierung natürlich automatisch erkannt und man muss das nur angeben, wenn man es expizit anders haben will.


    Zahlen sind hingegen eher einfach: Hier hat sich beim 6502 das "$" als Kennzeichnung weitgehend durchgesetzt. (Beim Z80 auf dem CPC hingegen "&"). Binärzahlen erhalten ein "%" als Präfix. Bei Oktalzahlen bin ich mir überhaupt nicht sicher, ob man die überhaupt braucht. Mein Assembler kennt sie gar nicht.

    $, &h, &, %. Oder B und O als Postfix für Binzahlen bzw. Oktalzahlen.


    Was die Pseudoopcodes anbelangt, so lassen sich einige standardisieren bzw. der Assembler kann verschiedene Schreibweisen unterstützen (z. B. "byt", "byte", ".byte", "!byte", "dc.b" usw.). Voraussetzung wäre lediglich, daß jede Schreibweise an sich eindeutig definiert ist.

    DB, .DB, DW, .DW - das war halt AVMAC-Syntax.


    Trotzdem wird eine Standardisierung nicht funktionieren, denn nicht standardisierbar sind die unterschiedlichen Ansätze eines Assemblers bei der Codeerzeugung und die damit verbundenen unterschiedlichen Schreibweisen. Soviel ich weiß, ist der ACME-Assembler (oder auch das C64Studio) eher dateiorientiert, wohingegen sich beispielsweise mein Assembler um Dateiformate überhaupt nicht kümmert. Wie der Programmierer den erzeugten Code speichert, ist hier allein seine Sache. Der Vorteil dieser Methode liegt darin, daß der Assembler dadurch erlaubt, direkt (auch mehrere) .d64-Images oder .adf-Images zu erzeugen, wozu auch gleich besondere Pseudoopcodes angeboten werden wie ".c64 skew" oder ".amiga bootblock". Da diese unterschiedlichen Vorgehensweisen der Assembler bzw. damit verbunden auch die Quelltexte nicht vereinbar sind, ist eine allgemeine Standardisierung per se nicht durchführbar.

    Vermutlich kenne ich C64Studio zu wenig um das zu verstehen. Mein Assembler erzeugt einfach BIN- oder PRG-Files. Wenn ich D64 haben will, macht das ein nachgeschaltetes Tool wie z.B. c1541.exe von Vice. Das ist definitiv nicht Aufgabe eines Assemblers. Aber C64 Studio ist ja mehr als ein Assembler.

  • Und dann wäre da noch das Thema Prozduren ("PROC") und lokale Labels.


    Bei mir sieht das derzeit so aus:


  • Da geht's schon wieder los

    ^^

    DB, .DB, DW, .DW

    usw. usf. Genau. Meine kleine Liste erhebt keinen Anspruch auf Vollständigkeit. Ich wollte nur verdeutlichen, wieviele unterschiedliche Schreibweisen es gibt, die rein theoretisch ein Assembler alle unterstützen könnte, sofern sie in sich klar definiert sind.

    Das ist definitiv nicht Aufgabe eines Assemblers.

    Wieso nicht? Ein d64/adf-Image ist doch auch nichts anderes als eine Binärdatei. Der wirklich wichtige Unterschied zu einer C64-Prg-Datei (wie sie Acme erzeugt) ist, daß das Diskettenimage die 64kb-Grenze überschreitet und damit einen anderen Adreßraum verlangt (vom ebenfalls eingebauten 68000-Assembler ganz zu schweigen). Daher wird man in diesem Punkt keine Standardisierung erzielen können.

  • [ASL A] war aber Standard (weil von MOS vorgegeben).

    ASL A ist nur eine von mehreren möglichen Mnemonik-Schreibweisen ein- und desselben Opcodes.


    Die zuallererst genutzte Syntax, die man in ganz alten Quellcodes findet, hängt die Adressierungsart direkt an den Opcode, also z.B. "LDAIM 02" (ohne $ als Kennzeichnung für Hex!) an Stelle von "LDA #$02". Da wurde dann die Akkumulator-Adressierung auch explizit angeschrieben mit "ASLA" (ohne Leerzeichen).


    Das A hat sich in der nächsten Iteration der Schreibweise für die Schiebebefehle dann noch gehalten.


    Spätere Assembler haben diese Irregularität und Redundanz dann herausgeworfen. Damit haben alle 1-Byte-Opcodes einheitlich keine explizit angeführten Operanden mehr und die Akkumulator-Adressierung ist eben nur ein Sonderfall der impliziten Adressierung.


    Und nochmal, bevor Du und Bit Shifter sich wieder erneut auf den Schlips getreten fühlen: der Inline-Assembler von BBC BASIC verlangt genau die von euch beiden so geschätzte Schreibweise. Ich komme einfach mit beiden Schreibweisen zurecht und muß hier nicht als Zelote für die "einzig richtige Schreibweise" tätig werden. Echt jetzt.

  • Seufz, das hatten wir schon mal. Ich habe nichts gegen Leute, die das Argument bei der Akkumulator-Adressierung weglassen, aber diese Schlampigkeit anderen als "neuen Standard" aufdrücken zu wollen ist Unsinn. Ich verweise auf die im 1. Post genannte Literatur, alle Autoren sind sich da einig. Implied Befehle haben die Eigenschaft, dass sie genau EINE Adressierungsart kennen und deshalb keinen Operanden brauchen. Die vier Bitschiebebefehle (ASL, LSR, ROL, ROR) kennnen fünf Adressierungsarten und gehören deshalb nicht zur Gruppe "Implied". Das hat nichts mit der Befehlslänge der Instruktionen zu tun.


    Solche obskuren Konstruktionen wie LDAIM oder ASLA (außer bei Tipfehlern, die ein Assembler erkennt und als Fehler kennzeichnet) sind mir nicht bekannt und ich programmiere seit 1978 in 6502 Assembler. Quellen ?


    Ich wollte ja eben einen Standard mit anderen zusammen einführen, um solche Diskussionen zu beenden, aber anscheinend sind einige hier im Forum mehr an Streiten und Recht haben wollen interessiert, als an fruchtbarer Zusammenarbeit. Schade eigentlich.

  • Also ich halte es für absolut utopisch, sämtliche Assembler-Entwickler dazu zu bewegen, ihre Syntax zu ändern. Da würde ich wenn dann eher ein Konvertierungstool schreiben, das verschiedene Assembler-Quellcodes in das Standard-Format bringen kann und von dort aus wieder zu einem der anderen Formate. WENN das ganze tatsächlich so wichtig ist. Ich bin mir nicht sicher wie groß das "Problem" ist, bisher habe ich wenn dann nur sehr kurze Dinge in meinen Code eingebunden und das war dann auch schnell von Hand angepasst. Aber ich bin auch kein Hardcore-Assembler-Coder, gut möglich dass da andere Leute mehr Anwendungsfälle dafür sehen.

  • Lieber selbst programmieren statt ueber Referenzen zu streiten ;-)
    Ich nutze selbst den XA Assembler und keine Macros. Alte Sourcen vom TASS, ACME und sonstwas liessen sich immer ohne weiteres vor- und zurueckkonvertieren.
    Teilweise allein in der Linux-bash.
    Wer wirklich programmiert duerfte sich wenig um dererlei scheren. Ich sah schon die konfusesten Sytanx Varianten. Solang alles eineindeutig ist - ist doch prima ;-)

  • Quellen?

    Guckst Du hier: http://6502.org/source/games/uchess/uchess.pdf, von 1976.


    Oder hier: http://archive.6502.org/public…cro/micro_01_oct_1977.pdf, von 1977.



    Ach so, noch was: Jeder, der funktionierende Programme in Maschinencode schreibt, kann wohl seine sieben Sinne sinnvoll beieinander halten. In diesem Zusammenhang von

    Schlampigkeit

    zu reden, finde ich reichlich unangebracht. Komm mal von deinem hohen Roß runter. Du beklagst die Diskussionskultur hier, die dir nicht zu deiner vorgefertigten Meinung zu passen scheint - dabei bist Du es, der hier Streß macht.

  • Und nochmal, bevor Du und Bit Shifter sich wieder erneut auf den Schlips getreten fühlen:

    So lang ist mein Schlips nicht. :D


    Aber die alten Quellen finde ich interessant. Hast du noch mehr Links?

  • Die zuallererst genutzte Syntax, die man in ganz alten Quellcodes findet, hängt die Adressierungsart direkt an den Opcode,

    Öhm- nö. Das war eine Parallelentwicklung/ Marotte vom Micro-Ware Assembler (und vielleicht ein paar anderen) aus der Single-Board-Computer-Ecke. KIM-1, SYM-1, AIM-65, Ohio Scientific... alles Systeme mit extrem wenig Speicher und meist langsamen Kassetten-Interfaces. Da war kein Platz für einen kmplexen Parser, also wurden manche Adressierungsarten mit 'Nachsilben' gekennzeichnet. Dollarzeichen für Hextahlen und automatische Erkennung von Zeropage-Adressen konnte er allerdings schon, auch ohne Postfix am Mnemonic.


    Nicht zu verwechseln ist das mit den Kürzeln aus der Opcode-Tabelle im Datenblatt.


    Die 'Akkumolator-Adressierung' stammt allerdings tatsächlich aus den Original-Unterlagen. Und ursprünglich kommt sie bom 6800, da war sie sogar sinnvoll, weil es zuwei Akkus gab, die man unterscheiden mußte. Beim 6502 ist es aber irgendwie gegen die allgemeine Semantik; alle anderen Register werden (als Quell- oder Zielregister der Operation) innerhalb des dreistelligen Mnemonics referenziert: INY, TXS... und daher ist das einzelne A irgendwann mal optional geworden. Vielleicht stammt das entfallende A sogar aus dem 'Raumsparwunder' von Micro-Ware; da hab ich aber auf die Schnelle keine Quelltexte mit Akku-Adressierung gefunden.

  • Das war eine Parallelentwicklung/ Marotte vom Micro-Ware Assembler

    Durch die Diskussion hier hab' ich das auch noch mal genauer nachgeschaut, und Du hast Recht - diese schräge Syntax kommt u.a. beim dem Micro-Ware Assembler und auch noch bei 2KSA (dem 2K-Symbolic-Assembler) zum Einsatz.
    Ist also nicht, wie von mir vermutet, :schande: ein Vorgänger der Syntax so wie sie heute üblich ist.
    Liest man sich die Tabelle in dem Micro Magazine (Link s.o.) auf der vorletzten Seite genauer durch, so kommt man darauf, daß für jeden der 151 dokumentierten Opcodes ein eigener Mnemonik abgestellt wurde - da kann man sich fast besser die Hex-Codes merken. :D



    Zitat von detlef

    Aber die alten Quellen finde ich interessant. Hast du noch mehr Links?

    Neben dem 2KSA gibt's noch einen 8080-Simulator für den KIM hier: https://www.pagetable.com/docs…02,%20KIM-1%20Version.pdf, auch in dieser obskuren Syntax. Hat mir verschiedentlich schon in den Fingern gejuckt, den mal zu portieren. :)