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

  • Vielen die in Assembler programmieren oder selbst einen Assembler/Cross-Assembler geschrieben haben ist dieses Problem bekannt:


    ES GIBT KEINEN STANDARD


    Zwar gibt es sehr viele schöne Bücher, die sich ausführlich mit der 6502 Programmierung befassen, wie:


    MOS Microcomputers Programming Manual "http://archive.6502.org/books/mcs6500_family_programming_manual.pdf"
    Rodnay Zaks: Programming the 6502 "https://archive.org/details/Programming_the_6502"
    Commodore Sachbuchreihe Band 1: Alles über den Commodore 64


    um nur einige zu nennen, aber die Regeln wie 6502 Sourcecode abzufassen ist beschränken sich auf (zu) Weniges:


    Die Benennung der Mnemonics, Darstellung von Sedezimalzahlen (auch Hexadezimal genannt) und die Syntax für das Operandenfeld und die Adressierungsarten.
    Was komplett fehlt sind Standards für sogenannte Pseudo-Ops. und Features, die oft allerdings erst durch Crossassembler auf leistungsfähiger Hardware möglich wurden.
    Dazu einige Beispiele:



    Konstantentypen: Binär, Oktal, Dezimal, Hex
    Label: Länge, Zeichensatz, Delimiter, Gültigkeitsbereich
    Strings: Delimiter, Zeichensatz, Escape-Sequenzen
    Daten Pseudo-Ops.: .DATA, .BYTE, .DB, .WORD, .FILL, .BSS, .STRING, .ASCII, uva.
    Format für Object-Files, Binaries, Executables, Relocatable Object-Files
    Bedingte Assemblierung: #if, #elseif, #else, #endif
    MACROS
    Optimierungen: Branch-Optimierung, ZeroPage Adressierung


    Dies alles ist meines Wissens nie standardisiert worden, sondern jeder Entwickler eines Assemblers (mich eingeschlossen)
    hat dies nach eigenem Gutdünken selbst entschieden.


    Dies hat leider dazu geführt, dass Assembler Quellttexte nicht portabel sind, sondern entweder mit einem bestimmten
    Assembler assembliert werden müssen oder in eine andere Syntax portiert werden müssen.



    Hier möchte ich jetzt gern ansetzen und eine Initiative ins Leben rufen die das


    "65xx family programming reference manual"


    schreibt, aufbauend auf dem MOS Manual und es ergänzt durch alles, was ein Assembler an zusätzlichen Features bietet.


    Mitglieder dieser Initiative sollten vorzugsweise Entwickler von Assemblern sein, die ihre Produkte vergleichen,
    diskutieren und anpassen. Mir ist durchaus klar, dass jeder Entwickler seine Lösung für die beste hält und sich
    schwer tun wird, sein Produkt zu verändern, aber man kann es ja mal versuchen ;)


    Falls sich genügend Teilnehmer finden würde ich auch vorschlagen, das ganze auf eine internationale Ebene zu bringen
    und Assembler-Entwickler ausfindig zu machen und zur Teilnahme einzuladen. Dann müsste die Kommunikation
    natürlich auf Englisch stattfinden.


    Doch zunächst einmal möchte ich die Idee hier zur Diskussion stellen und bin auf Eure Stellungnahme gespannt.


    :winke:

  • Doch zunächst einmal möchte ich die Idee hier zur Diskussion stellen und bin auf Eure Stellungnahme gespannt.

    Kann man nicht einen Cross-Assembler entwickeln, der eine einfache interne Programmiersprache enthält, die es dem Programmierer ermöglicht seinen Assembler entsprechend anpassen zu können?

  • Kann man nicht einen Cross-Assembler entwickeln, der eine einfache interne Programmiersprache enthält, die es dem Programmierer ermöglicht seinen Assembler entsprechend anpassen zu können?

    Ich fürchte, das würde die ganze Sache verkomplizieren, statt die Quellcodes portabler zu machen.
    Ein ganz pragmatischer Ansatz ist z.B. neben der Standard- oder selbst definierten Syntax auch andere zuzulassen,
    soweit es keine semantischen Konflikte gibt.


    So können Label z.B. mit oder ohne abschließenden Doppelpunkt akzeptiert werden.
    Oder es wird ein Standard MACROS definiert, aber andere MACRO Syntax Versionen werden akzeptiert,
    solange sie nicht zu Widersprüchen führen.

  • Ich fürchte, das würde die ganze Sache verkomplizieren, statt die Quellcodes portabler zu machen.

    Dann könnte man aber für jeden Assembler das entsprechene Syntaxmodul nachladen und bräuchte nicht über mögliche Standartisierungen diskutieren.

  • Standard?? - Das haben wir nicht mal in der EU bei Sprache, Einheiten, etc geschafft.... Das hab ich noch nicht mal in der Familie geschafft (4 Generationen), vielleicht ist das das Geheimnis der Evolution ... Immer nach dem Motto der Jungen "Ich mach alles anders"...
    Wichtig ist dass man einfach kurz in der Anleitung nachsehen kann ^^

  • Wir alle hier auf diesem kleinen Planeten durchleben die Zeit doch vorwärts, von daher betrachte ich die Beschäftigung mit einem möglichen Standard als absolute Zeitverschwendung!


    Die Tools existieren bereits und man muss sich nur mit deren Eigenheiten befassen, dauert ein paar Stunden dann ist es drin. Die Anzahl an neuen Tools bezüglich des 6502 sind locker an einer Hand abzuzählen. Wozu also ein Standard? Dass sich diese paar Entwickler daran halten? Und wenn nicht? Wenn etwas nicht im Standard enthalten ist, was der Entwickler gerne implementieren möchte?


    Wozu sollen die Programme von einem Assembler zu einem anderen portierbar sein? Dann brauche ich die Vielfalt an unterschiedlichen Assemblern ja gar nicht mehr...


    So schafft man eine Monokultur!


    Nur meine Meinung...


    Gruß
    Thomas


    PS: Selbst heute gibt es bei anderen 8-Bit-Controllern unterschiedliche Schreibweisen...

  • Wozu sollen die Programme von einem Assembler zu einem anderen portierbar sein? Dann brauche ich die Vielfalt an unterschiedlichen Assemblern ja gar nicht mehr...So schafft man eine Monokultur!

    Ich nehme mit Staunen zur Kenntnis, dass der Vorschlag Quellcodes portierbar zu machen nicht nur keine Befürworter findet, sondern sogar mehrheitlich abgelehnt wird. Man lernt immer wieder dazu. Während meiner Arbeit war ich froh vom schlecht standardisierten FORTRAN zum ANSI-C wechseln zu können. Aber die Retro-Kultur ist wohl eher ein naturbelassener Ökosumpf als eine gepflegte Gartenanlage und vielleicht ist das auch gut so 8o

  • ES GIBT KEINEN STANDARD

    Das ist genau der Grund, warum ich aktuell mit meinem eigenen Assembler arbeite.
    Ich assembliere des öfteren alten Quellcode (z.B. meine alten Programme aus den 80ern oder das DOS der PET-Floppies).
    Neuere Assembler ignorieren leider oft die alte Syntax (wir hatten ja gerade die ausführliche Diskussion zu den Akkumulator-Befehlen).
    Deswegen sind die meisten neueren Assembler für mich nicht einsetzbar.
    Und wenn ich irgendwelche Quellen bekomme, die mein Assembler nicht übersetzt, dann passe ich den Assembler an und nicht den Quelltext.


    Wenn jetzt ein neuer Standard definiert wird, hilft mir das bei alten Quellen leider überhaupt nicht.
    Aber ich nehme gerne die hier definierten Standards in meinen Assembler auf und bin auch gerne bereit, Assemblercode, den ich öffentlich mache, nach diesem Standard zu coden.

  • Endlich doch eine verwandte Seele :rolleyes:
    Ich denke ganz genauso wie Du und habe aus den selben Gründen meinen eigenen Assembler geschrieben.
    Ich wollte auch keinen neuen Standard kreieren, sondern aus den bestehenden Assemblern eine Schnittmenge bestimmen,
    auf die sich alle einigen können. Aber die bisherigen Reaktionen waren nicht sehr ermutigend.
    Hast Du vielleicht Lust Dich mit mir über Assembler auszutauschen ?
    Mein Assembler ist verfügbar unter: "https://github.com/Edilbert/BSA"
    Ist Deiner ebenfalls öffentlich verfügbar oder würdest Du mir den Code über PN zur Verfügung stellen ?

  • wenn ich irgendwelche Quellen bekomme, die mein Assembler nicht übersetzt, dann passe ich den Assembler an und nicht den Quelltext.

    Dann mach' ich wohl irgendwas verkehrt. :whistling:


    Ich mache mir schon die Mühe, "gefundenen" Code an die Syntax anzupassen, die der Assembler verwendet, mit dem ich arbeite. Da ist es mir absolut egal, nach welchem "Standard" die Originalquelle abgefaßt ist: blind will ich da ohnehin nichts übernehmen und während ich den Code anpasse, bekomme ich auch schon heraus wie er funktioniert.


    Für Archivzwecke wird die Originalquelle natürlich behalten.

  • Dann mach' ich wohl irgendwas verkehrt. :whistling:

    Das ist auf keinen Fall verkehrt sondern eine andere Art ein Problem zu beheben und ich kann die Gründe dafür auch nachvollziehen.
    Die Variante den Assembler dem Quellcode anzupassen ist schon deshalb nicht so weit verbreitet, weil die Zahl der Assembler-Entwickler doch eher klein ist.

  • Ich mache mir schon die Mühe, "gefundenen" Code an die Syntax anzupassen, die der Assembler verwendet, mit dem ich arbeite.

    Für Quellen, die ich genau einmal assembliere, um ein Listfile mit Adressen zu bekommen und um zu prüfen, ob ein Assembler-File mit einem anderen Binär-File identisch ist, ist mir das deutlich zu viel Aufwand.

  • Ich denke ganz genauso wie Du und habe aus den selben Gründen meinen eigenen Assembler geschrieben.

    Wobei ich meinen Assembler schon in den 80ern geschrieben habe (damals in C), weil es damals kaum brauchbare und bezahlbare Cross-Assembler gab.
    Und deswegen war die Syntax auch zunächst an die damals erhältlichen Cross-Assembler angelehnt war (z.B. AVMAC).

  • Für Quellen, die ich genau einmal assembliere, um ein Listfile mit Adressen zu bekommen und um zu prüfen, ob ein Assembler-File mit einem anderen Binär-File identisch ist, ist mir das deutlich zu viel Aufwand.

    Ich hatte unlängst das hier zwischen: Portierung (a la: hebt die Titanic!) eines Hilfsprogramms von ca. 2 KB Objektcode aus dem KERNAL der 264er Maschinen auf den VC-20. Der beteiligte Disassembler und mein Assembler haben leicht unterschiedliche Syntax.


    Mit einmal assemblieren war es da natürlich nicht getan. Ich habe da nicht nur Labels eingesetzt, um den Code frei verschiebbar zu machen, [1] die genutzten Datenbereiche mußten auch umgesetzt werden. Dann stellte sich im Laufe der Programmanalyse heraus, daß das Original mehrere, ganz fiese Bugs hat - u.a. einen Stack-Overflow, der sich erst bemerkbar macht, wenn man im Prompt zu oft etwas syntaktisch falsches eingibt. Also, ab auf den OP-Tisch, Drähte überall: diese Bugs wurden natürlich sauber behoben. Zum Schluß dann noch *vorsichtige* Funktionserweiterungen und nach ca. 2 Monaten und 34 Builds in Sonn- und Feierabendsprogrammiererei war das Ding im Kasten. :D


    Die Hauptdarsteller dieses Dramas: TEDMON und der Inline-Assembler von BBC BASIC. 8o




    [1] dazu nehme ich übrigens zwei selbstgeschriebene C-Programme her, welche mir die Absolutadressen liefern bzw. in den Operanden durch Labels ersetzen, *sofern* die Adresse (ggfs. händisch mit +/- 1 angepaßt) im Bereich liegt. Herauszubringen, ob ein Immediate-Operand das Low- oder Highbyte einer Adresse im Code ist, verlangt aber immer noch gutes Augenmaß. :bgdev

  • Der beteiligte Disassembler und mein Assembler haben leicht unterschiedliche Syntax.

    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).

  • Was die Adressierungsarten anbelangt, so dürften diese (mit Ausnahme des unlogischen "ASL A") weitgehend syntaktisch gleich gekennzeichnet werden:
    #<ausdruck>
    "<ausdruck>" (zeropage oder absolut)
    "<ausdruck>, x" (zeropage oder absolut)
    "<ausdruck>, y" (zeropage oder absolut)
    "(<ausdruck>, x)"
    "(<ausdruck>), y"
    Andere Schreibweisen wie "@<ausdruck>, x" für "(ausdruck, x)" und "@<ausdruck>, y" für "(<ausdruck), y" haben sich nicht durchgesetzt. Problematischer wären allerdings die Adressierungsarten beim 65816.


    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.


    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.


    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.


    Kurz gesagt: Bei vielen Punkten kann man sich wohl auf eine Schreibweise einigen oder besser dem Assembler erlauben, auf bestimmte Schreibweisen umzuschalten, da es sich lediglich um einfache Variationen handelt. Bedenken sollte man jedoch, daß es Assembler gibt, die nicht nur den 6502 unterstützen, sondern auch andere Prozessoren, und daher ihre Schreibweisen und Pseudoopcodes auch in Hinblick auf diese ausgerichtet haben.


    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.