Hallo,
mich würden mal eure Schätzungen interessieren, wie viele Stunden man
für die Entwicklung eines Cross-Assembler ansetzen müsste. Die CPU kennt
256 Befehle und in die Arbeitsweise der CPU müsste man sich auch noch
einarbeiten.
Man schreibt die Mnemonic in ein Textfile und nutzt für Sprungziele
Labels. Natürlich gibt es die üblichen EQUs für Konstanten. Die
Labeltabelle soll unten angefügt werden, einmal nach Reihenfolge und
einmal sortiert nach Namen. Der Quellcode soll mit hinzugefügten
Zeilennummern und den Opcodes und Adressen ausgedruckt werden können.
Funktion: Man startet den Cross-Assembler mit Angabe eine Startadresse
und der analysiert nun das Textfile. Fehlermeldungen werden erzeugt wie
Label doppelt oder Sprungziel nicht vorhanden. Sprungdistanz zu weit
usw. Und Syntax Fehler. Der erzeugte Code soll dann noch so aufbereitet
werden, dass er mit einer Checksum direkt in ein Zielsystem übertragen
werden kann.
Das Ganze mit einer ausführlichen Anleitung, so dass sich ein jeder
einarbeiten kann und keine Fragen offen bleiben. Das Tool muss
fehlerfrei laufen, darf also keinen fehlerhaften Code produzieren.
Stabil laufen soll das Ganze natürlich auch noch. Also ein richtig
astreines Produkt.
Dann bin ich mal auf eure Schätzungen gespannt.
Viele Grüße von Mike
Die Opcodes erkennen ist Peanuts. Was die meiste Arbeit macht, sind die
ganzen anderen Features: Expressions, Labels, Macros, bedingte
Assemblierung, Multi-Pass, Sections, Linken, etc.
Anstatt das alles neu zu schreiben, wäre es wohl sinnvoller, einen
vorhanden Assembler um deine CPU zu erweitern bzw auf sie umzustellen.
Hi,
mit den heute zur Verfügung stehenden Tools halte ich das - in einer
simplen Version - in einer Woche für möglich (sozusagen als
Machbarkeitsstudie). Sobald dann aber Optimierungen, komplexere
Ausdrücke etc. genutzt werden sollen, lässt sich der Aufwand für ein
solches Projekt ins unermessliche treiben.
Grüße,
Tommy.S
foobar schrieb:> Die Opcodes erkennen ist Peanuts.
Sicherlich, das ist aber der kleinste Teil der Übung. Richtig los geht
es mit dem, was dem Opcode folgt und dem ganzen drumherum.
Wir hatten mal vor Urzeiten in der Ausbildung so ein System (kein PC),
wo man die Mnemonik eintippen konnte und der Assembler jede Zeile gleich
übersetzt hat. Die Sprungadressen durfte mal selber ausrechnen und
eingeben. Wollte man in das fertige Programm einen Befehl einfügen,
durfte man alles nochmal neu rein hacken. Eine Adresse falsch berechnet,
alles neu rein hacken :-( Mehr wie ein Fünfzeiler war eine Zumutung.
Damals habe ich mir überlegt, wie man so einen Assembler programmieren
müsste, damit man vernünftig damit arbeiten könnte. Ein damaliger und
wirklich pfiffiger Ausbilder hat mir dann erklärt, auf was man alles
achten müsse. Daraufhin habe ich das Ganze ganz schnell beerdigt.
Heute ist es selbstverständlich, dass man zu einem Entwicklungssystem
einen Assembler mit allen Schikanen dazu bekommt, der nicht mal was
kostet. Trotzdem scheint mir der Aufwand dafür nicht unerheblich. Das
fertige Produkt dann auf Fehlerfreiheit zu prüfen ist sicher nicht ohne.
Wo es doch keine Software gibt, die fehlerfrei ist.
> mit den heute zur Verfügung stehenden Tools halte ich das - in einer> simplen Version - in einer Woche für möglich
In einer Woche hätte ich mal eben die Arbeitsweise einer neuen CPU
verstanden (hoffentlich).
Mike. H schrieb:> Dann bin ich mal auf eure Schätzungen gespannt.
Da kann man beliebig viel Arbeit investieren, oder man nimmt so etwas
wie einen Meta-Assembler - ein Programm, das den Assembler erzeugt,
meistens auf Basis von Tabellen mit z.B. Opcodes.
Die Fragestellung ist ja nicht sehr aktuell, es gab früher entsprechend
erstellte Assembler-Familien z.B. von Avocet (AVMAC48 usw.) und auch
Open Source Projekte, Namen fallen mir nicht mehr ein, aktuell habe ich
gefunden:
https://www.mpeforth.com/cross32.htm
Deine Beschreibung enthält hauptsächlich die gewünschten Ausgaben, aber
das ist simpel, nur einfach Arbeit, wenn das Object-File mal erstellt
ist.
Wilhelm.W schrieb:> Damals habe ich mir überlegt, wie man so einen Assembler programmieren> müsste, damit man vernünftig damit arbeiten könnte
Der erste Schritt: Assemblieren mit 2 oder mehr Durchgängen, üblich sind
2-Pass-Assembler, um u.a. Forward-Referenzen aufzulösen.
Georg
Ich hatte so etwas Ende der 80er in Turbo Pascal 4.0 realisiert
(inklusive eines Fullscreen-Editors).
Das ganze war ein sogenannter tabellengestützter Assembler und konnte
Prozessoren MCS48, MCS51, 8085, Z80, GameBoy-CPU und 6502.
Die ersten Dinge gingen schnell, aaaaaaaaaaber dann:
Mein Assembler (war absolut nicht vollwertig), denn er kannte keine
bedingte Assemblierung, er kannte keine Makros, er kannte keine
Segmentierung.
Er hat einfach die Mnemonics übersetzt und in einem ersten Pass
Sprungziele berechnet die er in einem zweiten Pass an den entsprechenden
Stellen eingesetzt hatte.
Jetzt weiß ich nicht wie gut du bist (und wie "gut" ich damals war, sooo
schlecht war ich nicht).
Das ganze Ding hätte ein Monatsprojekt werden sollen (damals) im Rahmen
der Meisterschule werden sollen, damit meine Kollegen MCS-51 und 8085
einfacher handhaben konnten.
Zusammen mit einem EPROM-Simulator der über die parallele Schnittstelle
angesprochen wurde hatte das ganze unterm Strich ein Jahr gedauert.
Übel war, dass ich 3 oder 4 Jahre später (ich hatte tatsächlich sehr
lange damit gearbeitet), einen Fehler in einem Projekt gesucht habe,
dass ich damit erstellt hatte.
Ich hab ewig im Projekt gesucht bis ich bemerkt hatte, dass eine (von
mir bis dahin nicht verwendete) Mnemonic eines MCS-51 in der Tabelle
falsch angegeben war.
---------------------------------------
Egal wie gut du bist, der Aufwand den du treiben musst um deinen
gegebenen Anforderungen (vor allem hinsichtlich Fehlerfreiheit) gerecht
zu werden sind enorm.
Heutzutage gibt es viele viele gute Open-Source Assembler. Nimm einen
und passe diesen deinen Belangen an.
Ralph S. schrieb:> Mein Assembler (war absolut nicht vollwertig), denn er kannte keine> bedingte Assemblierung, er kannte keine Makros, er kannte keine> Segmentierung.
zumindest die ersten beiden Probleme könnte man kreativ lösen, indem man
einen C-Präprozessor nutzt, durch den man den Source zuerst durchjagt.
Hallo Mike,
als die Gummistiefel noch aus Holz waren hab ich einen Assembler,
welcher über Befehlstabelle gesteuert wird, geschrieben und später hier
veröffentlicht.
Beitrag "Universeller Assembler (DOS-Fosil)"
Ist ein DOS-Programm, sollte in einem DOS-Fenster laufen. Beschreibung
ist in Textform dabei (Asmdoc.txt). Die Übersetzung wird durch eine
Tabelle gesteuert und diese kann man selbst definieren. Möglicherweise
kannst du damit auch eine Tabelle für deinen Prozessor dazu bauen.
Zwei Beispieltabellen (8052, 8085) sind in Textform dabei. In
Tabellenform liegen 8051, 8052, 8085, 8086, 80515, 89S8252 und Z80 bei.
Der Tabellenkonverter "Tabkonv2.exe" (Text -> Binär) ist Teil des
Paketes, wodurch ein erstellen/pflegen der Tabellen möglich ist.
Viel Erfolg für dein Projekt. Tom
Ralph S. schrieb:> Mein Assembler (war absolut nicht vollwertig), denn er kannte keine> bedingte Assemblierung, er kannte keine Makros
GCC-Preprozessor :)
Mampf F. schrieb:> GCC-Preprozessor :)
Schmunzel, wie gesagt: Es war damals in Turbo Pascal 4.0 geschrieben
gewesen!
Ich denke nicht, dass der TO einen Assembler schreiben wird, der Aufwand
einen besseren zu schreiben als die, die eh schon als OpenSource
verfügbar sind, ist imens.
Habe noch vergessen dass dich vor Allem der Aufwand interessiert. Der
Assembler wurde nicht in einem Rutsch während der Arbeitszeit
geschrieben, sondern immer wenn Zeit dafür war. Die Programmiersprache
ist C. Ein lauffähiger Assembler war nach etwa zwei Monaten fertig, der
Ausbau zum brauchbaren Programm mit Macros, bedingter Assemblierung usw.
dauerte ca. drei Monate. Bis die Unzulänglichkeiten und gefundenen
Fehler beseitigt waren vergingen mehrere Jahre und ich weiß, man könnte
heute noch daran arbeiten.
So im Nachhinein also ein halbes Jahr für ein gut brauchbares Programm
und viele Stunden für die Fehlerbeseitigung/Pflege.
Gruß. Tom
Ralph S. schrieb:> Ich denke nicht, dass der TO einen Assembler schreiben wird, der Aufwand> einen besseren zu schreiben als die, die eh schon als OpenSource> verfügbar sind, ist imens.
Kommt manchmal vor, dass man das machen muss, wenn man einen Assembler
für eine CPU braucht, für den es keinen gibt :shrug:
TomA schrieb:> der> Ausbau zum brauchbaren Programm mit Macros, bedingter Assemblierung usw.> dauerte ca. drei Monate.
Das würde man ja jetzt nicht mehr so machen ... Wie gemeint, für Macros
oder bedingte Assemblierung kann man den GCC-Preprozessor gut benutzen.
Ich finde das Thema interessant - ich hatte mir die letzten Wochen mal
über einen Assembler Gedanken gemacht, da ich genau den Fall hätte,
einen Assembler für eine CPU bauen zu müssen, für den es keinen gibt.
Ich hab mitte der 90er auf meinem Amiga 500 in GFA-Basic einen
Pic16F84-Assembler gebaut.
Mit Labels und ein paar erweiterten Opcodes, ohne bedingte
Assemblierung, Makros und so'n Werks.
Zwei-Pass, ca. 15 Minuten Compilierzeit für effektiv gerade mal 1kWords
Ergebnis, erstmal Label einsammeln und Adressen mitzählen, dann im 2.
Durchlauf stumpf Opcodes in Tabellen suchen.
GFA war rasend schnell, nuja, ein Atari-Basic auf'm Amiga umgestrickt
soweit ich weiß, klappte aber einwandfrei.
Sehr wie jjflash's Kram. :)
Und ein Programmierprogramm (und eine Hardware natürlich) war auch
dabei, so konnte man zwischen Feierabend und Bett glatt 4 oder 5
Iterationen seines Projekts schaffen.
Meine Coazubis fanden's geil: Larsen-Scanner, Codeschloss, PC-Tastatur
an Amiga, Joysticks als PS2-Maus und und und.
Das zu erstellen hat so 3 Wochen gedauert, jeweils ein paar Stunden nach
Feierabend.
Mike. H schrieb:> Also ein richtig astreines Produkt.
Astreines Produkt bedeutet 6 Mannmonate extra. Geht schon mit der Frage
los auf was für Rrchnersystemen der Assembler laufen soll. Wie ist das
Lizenzmanagement? Wie soll die Software das Kompilat auf das Zielsystem
laden? Soll der Assembler in eine existierende IDE integriert werden,
oder eine neue IDE entwickelt werden (nochmal plus 6 Monate).
Was bedeutet fehlerfrei? Bewiesen mit formaler Verifikation? (1 Mannjahr
extra). Muss dazu ein verifizierter Compiler eingesetzt werden
(Extrakosten). Oder bedeutet fehlerfrei nur ausgiebig getestet?
Mike. H schrieb:> Das Tool muss> fehlerfrei laufen, darf also keinen fehlerhaften Code produzieren.> Stabil laufen soll das Ganze natürlich auch noch. Also ein richtig> astreines Produkt.
Dann würde ich das nicht neu schreiben sondern eine weitere Architektur
in ein vorhandenes Projekt wie GNU Binutils rein hacken.
Binutils kennt schon einige Architekturen, da müsste man eine neue CPU
mit überschaubarem Aufwand rein bekommen.
Wenn man eine höhere Programmiersprache (Java, Python, C#, Scala...)
nutzt und fleißig Gebrauch der gebotenen Container-Klassen (insb. Maps
und Listen) macht, sollte sich die Entwicklungszeit drastisch reduzieren
lassen. Vielleicht ist eine funktionale Programmiersprache hier genau
richtig, weil es um Transformation von Datenstrukturen geht.
Interessant wird noch die Auswertung von mathematischen Ausdrücken, à
la:
1
.equ PRESCALER, (F_CPU / F_UART) - 1
oder
1
ldr r0, [r1, #(LUT - . + 4)]
Um diese zu parsen kann man einen Parser-Generator wie ANTLR oder
Boost.Spirit nutzen, bzw. nutzt diesen direkt für das komplette
Assembly-File.
Bei ARM und ELF muss man eine Reihe von unterschiedlichen
Immediate-Formaten beherrschen und kodieren, ggf. PC-relative o.ä. Je
nach Zielplattform braucht man etwas ähnliches.
Die Schätzung von Monaten oder Jahren halte ich für übertrieben; wenn
alle Rahmenbedingungen klar sind (ISA, Ausgabe-Format (ELF?), ggf.
Linker, Auflösung von Symbolen, ...) und die betreffenden Tools bekannt
sind (Sprache, Bibliotheken, Parser-Generator) sollte das zügiger
machbar sein, wenn man nicht gerade C nutzt und bei Adam und Eva
anfängt.
Wilhelm.W schrieb:> Damals habe ich mir überlegt, wie man so einen Assembler programmieren> müsste, damit man vernünftig damit arbeiten könnte. Ein damaliger und> wirklich pfiffiger Ausbilder hat mir dann erklärt, auf was man alles> achten müsse. Daraufhin habe ich das Ganze ganz schnell beerdigt.
Na ja, ich habe vor Jahren als Schüler als eine meiner ersten
Fingerübungen mal sowas in Basic für einen 6809 geschrieben, mit
ziemlich genau den Featurs, die der TO auch will (also nur Opcodes,
Labels, .EQU und .ORG). Der Aufwand ist doch überschaubar. Die hier
schon genannte Woche Aufwand passt.
Oliver
Mike. H schrieb:> Die CPU kennt 256 Befehle und in die Arbeitsweise der CPU müsste man> sich auch noch einarbeiten.
Der Aufwand hängt nur ein einEM geringen Ausmaß vom Code Umfang ab.
Wesentliche Fragen für den Aufwand sind:
- Linkfähigkeit,
- Makrofähigkeit,
- Fehlerpräsentation
- Einhaltung von Standards
Mike. H schrieb:> mich würden mal eure Schätzungen interessieren, wie viele Stunden man> für die Entwicklung eines Cross-Assembler ansetzen müsste.
Für einen "full featured"-Assembler, also 2-pass, vernünftige
Expressions, macrofähig und mit einem brauchbaren Preprocessor würde ich
mal 6 Mannmonate eines absolut kompetenten Entwicklers schätzen.
Minimum. Vollzeit.
Und das Ergebnis wird danach zwar gut benutzbar (und so Gott will) auch
halbwegs fehlerfrei, aber immer noch weit entfernt von Perfektion (im
Sinne von optimaler Anpassung auf das Zielsystem) sein.
Das dürfte dann weitere Jahre der intensiven Nutzung des Werkes
erfordern...
c-hater schrieb:> Und das Ergebnis wird danach zwar gut benutzbar (und so Gott will) auch> halbwegs fehlerfrei, aber immer noch weit entfernt von Perfektion (im> Sinne von optimaler Anpassung auf das Zielsystem) sein.>> Das dürfte dann weitere Jahre der intensiven Nutzung des Werkes> erfordern...
Ich bin irritiert ... Ein Assembler übersetzt Mnemonics in Maschinencode
... Wieso denn Perfektion?
Entweder er macht es oder nicht ...
Und was für eine optimale Anpassung an das Zielsystem?
Ihr übertreibt aber etwas sehr ...
Man könnte einen Assembler als Linux Bash-Script mit sed, grep und awk
bauen, wenn es sein muss.
Und was hat das überhaupt mit Gott zu tun? Oo
c-hater schrieb:> Mampf F. schrieb:>>> Ich bin irritiert ... Ein Assembler übersetzt Mnemonics in Maschinencode>> Ein guter Assembler tut wesentlich mehr als nur dies.
Yep, und wir freuen uns alle, wenn wir mit tollen Werkzeugen arbeiten
dürfen. Aber der TO ist ein ganz harter Kerl, er braucht nur ein
Werkzeug welches ihm das Lesen der Mnemonik-Tabellen und eintippen per
Hex-Editor erspart. ;)
So wie man in den 80ern auf Heimrechnern Maschinencode geschrieben hat:
Basic Lader, der dezimale Datazeilen in einen Speicherbereich poked. Die
Übersetzung hat man mit den Instruction Tables aus dem jeweiligen
Handbuch (Z80, 6502, 68k) gemacht. :D
Scherz beiseite - wenn es so eine einfache Softcore-CPU aus der
PicoBlaze-Klasse ist, kommt man mit einem Minimalwerkzeug doch schon
ganz gut vorwärts.
Hab ich zu Ausbildungszeiten auch mal gemacht, war glaub ich ein 8085
oder sowas. Ich hab damals Borland-Pascal verwendet. Nach ein paar
Wochenenden und langen Abenden dazwischen kam dann was einigermaßen
funktionsfähiges heraus welches ungefähr den Umfang aus Post 1 hatte.
Frag nicht lang und fang einfach mal an. Am Ende wirst Du auf jeden Fall
klüger sein als zuvor und es wird nicht mehr gekostet haben als etwas
von Deiner Zeit. Du hast nichts zu verlieren. Tu es.
Jens M. schrieb:> Ich hab mitte der 90er auf meinem Amiga 500 in GFA-Basic einen> Pic16F84-Assembler gebaut...
Interessant, hier war es ein Intel 8085 und ebenfalls das sagenhafte
GFA-Basic von Frank Ostrowski auf einem ATARI ST. Der erste Versuch
endete in einer Sackgasse und ich konnte den Code von vielen Stunden im
Mülleimer versenken. Habe aber daraus gelernt, dass man die
Assemblierung in zwei Durchgängen durchführen muss: Erst die Labels
einsammeln und in Adressen überführen und erst dann kann man mit dem
Assemblieren beginnen. Jahre später las ich dann einen Artikel in der
c't über den 2-pass Assembler. Ich hatte das Rad also ein zweites mal
erfunden.
Funktionalität war punktgenau wie vom TO beschrieben. Aufwand war nahezu
die gesamte Freizeit des letzten Ausbildungsjahrs. Als die Kumpels in
den Ferien im Freibad lagen, habe ich den Assembler programmiert und
getestet. Hat mich damals einfach total begeistert.
Zum Testen habe ich mir ein "Programm" geschrieben, das alle Befehle
enthielt. Bei den Jumps, Calls und Returns in Abhängigkeit der Flags
musste man sich allerdings was überlegen, damit das Programm durch lief.
Das Programm dann in ein EPROM gebrannt und mit dem Philips PM3632
Logikanalyser disassembliert. In der Tat war die Prüfung des erzeugten
Codes auf Fehlerfreiheit ein ziemlicher Aufwand. Von der ersten Läufen
bis zu dem Punkt, wo man es hätte in fremde Hände geben hätte können,
war es ein weiter Weg.
Ich würde 6 Monate Vollzeit ansetzen, bis so ein Tool rund läuft. Wobei
es stark darauf ankommt, ob ein erfahrener und begnadeter Programmierer
am Werk ist, oder ein besserer Anfänger. Ersterer wird so ein Projekt
sicher eher aus dem Ärmel schüttelt. Man kann hier ja auch was von einer
Woche lesen.
Man hat auf jeden Fall richtig was gelernt, wenn man so ein Projekt bis
ganz zum Ende durchgezogen hat. Unter anderem, dass es gerade mal
Halbzeit ist, wenn es "läuft" ...
Schlafmütze schrieb:> und mit dem Philips PM3632 Logikanalyser disassembliert.
Nachtrag: Der Logikanalyser war mittels Testklammer an einer 8085-CPU
adaptiert, die mein Programm abarbeitete.
Ist ja genial, wieviele Atarianer hier rumlaufen. :)
Ich denke das geht heutzutage deswegen schneller, weil wir einfach
bessere Werkzeuge und das Internet als Nachschlagewerk haben. Ich würde
die Anforderungen des TO auch in weniger als einer Woche Vollzeit
erledigt sehen.
Zu Atari Zeiten hatte ich als Hauptliteratur den c't Sonderdruck 68k,
das Profibuch und den Tietze Schenk (aus der Schulbücherei).
Datenblätter habe ich mir auszugsweise im Elektronikladen kopieren
lassen. Ich habe während der Kollegstufe in einem Computerladen
ausgeholfen. Dadurch hatte ich noch recht günstigen Zugriff auf die
üblichen Heftchen.
Für meine Diplomarbeit würde ich mich heute nicht mehr trauen, mehr als
3..4 Wochen anzusetzen. Damals war das eine tolle Leitung, das in einem
halben Jahr hinzubekommen.
8085 kenn ich nicht, aber PIC hat den unschlagbaren Vorteil, das der
Befehl immer nur ein Wort lang ist.
Die wichtige Schleife war also nur eine Folge von IFs, denn die Befehle
kann man alle finden, immer PC eins weiter und "IF Befehl$=xxx THEN
Code=xxx ELSE IF..."
Wenn eine Zeile durch war und keins der IFs zugeschlagen hatte war ein
Schraubfehler drin, Label hatten ein : am Ende und # waren Kommentare.
Das war mit einfachen Stringoperationen zu schaffen...
Jens M. schrieb:> 8085 kenn ich nicht,
Daran, dass es Elektroniker gibt, die den 8085 nicht kennen, erkenne
ich, wie extrem alt ich sein muss.
Ich hab den 8085 gerne programmiert (und ich war so verrückt, weil ich
die Mnemonic des Z80 nicht mochte - ich bin halt Intel verseucht gewesen
damals - habe ich auch den Z80 mit Intel Mnemonic programmiert).
Wieviele von den 256 Befehlen werden denn auch tatsächlich genutzt?
Meist reicht die Implementierung von ca. 15-25 wichtigen Instruktionen
und sämtliche Bus und -Speicheroperationen sind schon mal
abgefrühstückt.
Tricky wird es erst bei segmentiertem Speicher, Floating-Point
Unterstützung etc...
>Das Tool muss>fehlerfrei laufen, darf also keinen fehlerhaften Code produzieren.
Das sicherzustellen, sind schon andere dran gescheitert...
Bei 256 Befehlen und angenommener Opcodebreite von 32bit kannst du ja
mal ausrechnen, was ein doofer Brute-force Testansatz durchrattern
darf...
Ralph S. schrieb:> Daran, dass es Elektroniker gibt, die den 8085 nicht kennen, erkenne> ich, wie extrem alt ich sein muss.
Naja, kennen tu ich ihn schon, aber programmiert hab ich in der Schule
mit dem Mikroprofessor, der war Z80, oder?
Zuhause ZX81.
In der Ausbildung hatten wir kurz den MFA, das ist ein 8085, aber das
war ein paar Wochen vor der und in der Zwischenprüfung, danach nix mehr.
Wirklich was großes damit gemacht haben wir nicht.
Und ich bin auch schon alt... ;)
Mike. H schrieb:> mich würden mal eure Schätzungen interessieren, wie viele Stunden man> für die Entwicklung eines Cross-Assembler ansetzen müsste.
Das hängt doch im Wesentlichen von deinen Programmierfähigkeiten, von
deiner Programmiersprache und von der Zielarchitektur ab.
Die Grundfunktionalität ist leicht zu schreiben.
Was aufhält, sind
1. Ausdrucksverarbeitung bei den Argumenten
2. bedingtes Assemblieren
3. Makros
Also setze mal 10..20 Stunden an - als grobe Schätzung.
Und ja, ich hab sowas schon mehrfach selbst getan. Mit der Zeit kriegt
man da ne gewisse Übung, dann geht's schneller.
W.S.
Schlafmütze schrieb:> Habe aber daraus gelernt, dass man die> Assemblierung in zwei Durchgängen durchführen muss: Erst die Labels> einsammeln und in Adressen überführen und erst dann kann man mit dem> Assemblieren beginnen.
Das war mal so, weil es im benutzten Rechner zuwenig Platz gab.
Heutzutage kann man sowas in einem Paß machen: Bei Argumenten, deren
Wert noch nicht bekannt ist, wird der betreffende Befehl in eine
zusätzliche Liste geschrieben. Nach dem Durchlauf des Passes werden
anhand dieser Liste dann die betreffenden Befehle "gepatcht". Und wenn
irgendwas in der Liste übrig bleibt, gibt's ne Fehlermeldung:
unbekanntes Symbol.
W.S.
Jonas B. schrieb:> Tricky wird es erst bei segmentiertem Speicher, Floating-Point> Unterstützung etc...
segmentierter Speicher? Du meinst vermutlich Harvard. Das geht ganz
leicht. Man muß lediglich zwei Speicherräume verwalten, wobei im
Datenraum eben nur Variablen, aber kein Code und keine Konstanten
plaziert werden darf.
Bei Gleitkomma geb ich dir Recht. Sowas ist bei vielen Plattformen
garnicht im Maschinencode vorhanden und wenn man da sich eine GK-Lib
selber geschrieben hat (ich z.B. für die PIC16Cxx), dann müßte man sich
quasi Pseudobfehle für eben diese Lib einfallen lassen, was aber den
Assembler auf eben diese Lib festnagelt. Makros an dieser Stelle sind
eher ungünstig, da zu unflexibel.
W.S.
Marcus H. schrieb:> So wie man in den 80ern auf Heimrechnern Maschinencode geschrieben hat:> Basic Lader, der dezimale Datazeilen in einen Speicherbereich poked. Die> Übersetzung hat man mit den Instruction Tables aus dem jeweiligen> Handbuch (Z80, 6502, 68k) gemacht. :D
na ja, vorher stand das Programm auf Karopapier und dann erst hat man
die HEX-Code oder Ganzzahlen Int eingetippt.
Bedienbare Assembler bekam man ja erst später als die Benutzergruppe
sich erweiterte.
>> Habe aber daraus gelernt, dass man die>> Assemblierung in zwei Durchgängen durchführen muss: Erst die Labels>> einsammeln und in Adressen überführen und erst dann kann man mit dem>> Assemblieren beginnen.>> Das war mal so, weil es im benutzten Rechner zuwenig Platz gab.> Heutzutage kann man sowas in einem Paß machen: Bei Argumenten, deren> Wert noch nicht bekannt ist, wird der betreffende Befehl in eine> zusätzliche Liste geschrieben. Nach dem Durchlauf des Passes werden> anhand dieser Liste dann die betreffenden Befehle "gepatcht". Und wenn> irgendwas in der Liste übrig bleibt, gibt's ne Fehlermeldung:> unbekanntes Symbol.
Ihr habt nicht genug in Assembler programmiert ;-)
Es gibt ne ganze Menge CPUs, bei denen die Befehlslänge von den
Operanden abhängig sind (z.B. short/long jumps). Oder man hat
Pseudo-Ops, die einen variablen Speicherbedarf haben (z.B. einen um
Speicher zu reservieren). Sind die Operanden noch nicht bekannt (z.B.
Ausdrücke mit Vorwärtsreferenzen), kennt man auch die Befehlslänge
nicht. Damit man Adressen für die folgenden Labels bekommt, rät man
eine Länge und arbeitet erstmal weiter. Im zweiten Pass überprüft man,
ob man richtig geraten hat - wenn nicht, nimmt man ne neue Länge (anhand
der jetzt ungefähr bekannten Symbole - korrekt sind sie nicht
unbedingt). Die folgenden Labels bekommen dadurch neue Adressen und es
wird ein weiterer Pass benötigt. Das macht man so lange, bis sich
Symbole nicht mehr ändern und man damit einen stabilen Zustand gefunden
hat. Wenn man Pech hat, oszillieren die Symbole und man findet keinen
...
Marcus H. schrieb:> Aber der TO ist ein ganz harter Kerl, er braucht nur ein> Werkzeug welches ihm das Lesen der Mnemonik-Tabellen und eintippen per> Hex-Editor erspart. ;)
Sowas nannte man damals(tm) ein "Monitorprogramm". Debug.exe von MS-DOS
z.B. fällt in etwa in diese Kategorie, ich habe aber auch auf
8Bit-Ataris anfangs mit sowas rumgeeiert.
Nö, sowas ist nicht wirklich ein Assembler, mit dem man auch komplexe
Programme schreiben kann.
Der Vorteil von sowas ist: es kann oft noch direkt auf dem Zielsystem
laufen, sozusagen "neben" der Anwendung. Sozusagen ein "in
place"-Debugger mit etwas Komfort.
c-hater schrieb:> Sowas nannte man damals(tm) ein "Monitorprogramm". Debug.exe von MS-DOS> z.B. fällt in etwa in diese Kategorie, ich habe aber auch auf> 8Bit-Ataris anfangs mit sowas rumgeeiert.>> Nö, sowas ist nicht wirklich ein Assembler, mit dem man auch komplexe> Programme schreiben kann.
Kenn ich vom C64. Das ist letztendlich ein stark aufgebohrter Hexeditor.
Es gab aber für den C64 auch mindestens einen guten Assembler, ich komm
nur nicht mehr auf den Namen, da war ein Editor dabei der hatte die
Tastenkürzel von Wordstar (Ctrl-K-B, Ctrl-K-C undsoweiter, so ähnlich
wie Joe's Editor).
Wie hieß denn dieser Assembler nochmal? Ich hab Jahre damit verbracht
und verzwickte Sachen damit gemacht aber ich komm nicht mehr auf den
Namen!
c-hater schrieb:
...
> Sowas nannte man damals(tm) ein "Monitorprogramm". Debug.exe von MS-DOS> z.B. fällt in etwa in diese Kategorie, ich habe aber auch auf> 8Bit-Ataris anfangs mit sowas rumgeeiert.
Haha, danke für das Stichwort. Als ich das Studieren angefangen habe,
hatte ich nur ein paar Atari STs (mein erster PC war ein P60, komplett
mit FPU-Bug). In der Informatikvorlesung haben wir 8086 Assembler mit
debug.exe geschrieben. Also in meinem Falle im Zimmer vom
Studentenwohnheim: PC-Emulator (DOS3?) auf dem Atari, dann per debug.exe
Code geschrieben und direkt in irgendwelchen Sektoren auf einer
DD-Diskette gespeichert.
Vom 68k kommend war die x86-Welt mit ihrem segmentierten Speicher, äh
sagen wir mal, ungewohnt?!
Genauso wie ARM Cortex M ungewohnt war, nach Jahren PIC und AVR.
> Nö, sowas ist nicht wirklich ein Assembler, mit dem man auch komplexe> Programme schreiben kann.
Nun enttäusch mich bitte nicht, mein Gutester. Wir schaffen das. ;)
Du koenntest Dir den "Macroassembler AS" anschauen (lass Dich nicht
durch den generischen Namen taeuschen):
http://john.ccac.rwth-aachen.de:8000/as/
Der unterstuetzt bereits so um die verschiedene 50 Prozessoren,
vielleicht ist Deiner schon dabei:
http://john.ccac.rwth-aachen.de:8000/as/cpulist.html
Wenn nicht sollte es nicht allzu schwer sein, ihn hinzuzufuegen!
ZigZeg
Tommy.S schrieb:> mit den heute zur Verfügung stehenden Tools halte ich das - in einer> simplen Version - in einer Woche für möglich (sozusagen als> Machbarkeitsstudie).
Mit den in den 70er Jahren zur Verfügung stehenden Tools hat man eine
simple Version in zwei, drei Tagen geschrieben und dann ein, zwei Jahre
in der Produktion verwendet. So lange, bis man für den Prozessor
kommerzielle und gleichzeitig bezahlbare Produkte bekam.
Es war damals einfach üblich, dass man, wenn nötig, so etwas schnell
zusammen hackte um ein System zu bootstrappen.
Besonders schnell ließ sich ein Crossassembler mit den Unix
Textprocessing-Tools zusammen bauen. Das war ein bekannter Trick. Aho,
Weinberger und Kernighan haben das später in ihrem Buch The AWK
Programming Language beschrieben
https://archive.org/details/pdfy-MgN0H1joIoDVoIC7 Kapitel 6.1 "An
Assembler and Interpreter".
Die selbe Idee, Textprocessing-Tools zu nehmen, steckt hinter dem in awk
und sed geschriebenen retargetable Assembler von Henry Spencer
http://doc.cat-v.org/henry_spencer/amazing_awk_assembler/ (Download des
Sourcecode am Ende der Seite).
Wer kein awk mag hat m4 oder später perl oder python genommen. Es gibt
sogar einen x64 Assembler in bash. Alles kein Hexenwerk. Nur alte Schule
und Textprocessing-Tools.
Dann ist mal auf die Idee gekommen, dass man mit C-Makros auch einen
universellen Cross-Assembler schreiben kann.
http://www.drdobbs.com/embedded-systems/a-universal-cross-assembler/222600279
Ganz die alte Schule verwendet er trotzdem awk als weiteren Pre- und
Postprocessor:
>> The effect is you might write:>>>> push FCON0 ; push a zero on the stack>>>> The awk script converts this to:>>>> PUSH(FCON0);>>>> Then the C preprocessor resolves it to:>>>> MOV(FCON0,FSTK_PUSH);>>>> Which itself resolves to:>>>> soloASM(0,0,0,0x304);> Sobald dann aber Optimierungen, komplexere> Ausdrücke etc. genutzt werden sollen, lässt sich der Aufwand für ein> solches Projekt ins unermessliche treiben.
Na, so schlimm ist es nicht. Vieles lässt sich mit weiteren Durchgängen
(Passes) erschlagen. Komfortfunktionen, wie Ausdrücke berechnen, kann
man, wenn das verwendete Tool Strings als Code eval()uieren kann, dem
Tool überlassen. Preprocessing / Macros bietet meist das
Textprocessing-Tool direkt, kann man mit dem Tool zusammen hacken oder
man nimmt einen weiteren Durchgang mit einem externen Macroprozessor
(sed, awk, perl, python, m4, C-Preprozessor ...) hinzu.
Peephole Optimizer, die sich in erster Näherung anbieten, sind
technische nicht schwer mit einem Textprocessing-Tool umzusetzen. Der
Aufwand steckt mehr darin die zu optimierenden Assembler-Fragmente zu
formulieren.
Wozu braucht man denn optimierende Assembler? Ich dachte
Assembler-Programmierer schreiben sowieso immer perfekten Code, den kein
Optimizer überbieten könnte...!
Duck und wech...
>> Für einen MSP430-Assembler in Go brauchte ich laut "git log" ca. 5>> Monate.>> Die meiste Zeit ging drauf, um Go zu lernen? :)
Nee :)
Wer C kann, kann wahrscheinlich schon >80% von Go.
Das Schwierigste war wahrscheinlich die Yacc-Bibliothek.
Niklas G. schrieb:> Wozu braucht man denn optimierende Assembler?
Versteh ich auch nicht. In Assembler programmiert man doch,
um die vollständige Kontrolle über den Code zu haben.
Auch wenn er vielleicht nicht optimal ist.
neugierig schrieb:> Mike. H schrieb:>> Die CPU kennt 256 Befehle>> Welche CPU?
Wurde leider bisher nicht beantwortet.
Es gibt auch CPU-Kerne, bei denen bestimmte Maschinenbefehle nicht
unmittelbar hintereinander folgen dürfen. Z.B. Renesas 78k0R (ein 16Bit
Risc uC). Oder 16-Bitter, die Speicherzugriffe, die >8Bit sind, nicht
auf ungeraden Adressen durchführen dürfen usw.
Da sollte ein guter Assembler zumindest eine Warnung generieren können.
>> Wozu braucht man denn optimierende Assembler?>> Versteh ich auch nicht. In Assembler programmiert man doch,> um die vollständige Kontrolle über den Code zu haben.> Auch wenn er vielleicht nicht optimal ist.
Eine Optimierung muss nicht eine der "verrückten" Transformationen sein,
die der GCC bei -O3 macht. Z.B., der MSP430 hat Konstantengeneratoren,
die, je nach Adressierungsmodus -1, 0, 1, 2, 4 und 8 erzeugen können.
Als Programmierer will man aber einfach
mov #1, r4
statt
mov 0(r3), r4
schreiben. Ein optimierender Assembler würde (zumindest m.M.n.) die 1.
Form durch die 2. ersetzen, was min. 1 Taktzyklus einspart.
Marten Morten schrieb:> Mit den in den 70er Jahren zur Verfügung stehenden Tools hat man eine> simple Version in zwei, drei Tagen geschrieben
da waren wir aber jünger :)
Die Prozessoren waren überschaubarer, der Speicher knapp, auf
aufgeblasene Ideen kam man ja mangels Speicher nicht.
Wer überblickt heute noch Windows oder ein komplettes Linux?
Schau dir das hier mal an:
https://www.embecosm.com/appnotes/ean10/ean10-howto-llvmas-1.0.html#idp112800https://en.wikipedia.org/wiki/LLVM#Back_ends
Wenn ich das richtig verstanden habe, dann ist das llvm-mc Projekt ein
Projekt, dass es sich zur Aufgabe gemacht hat, system- bzw. CPU
spezifische Assembler zu schreiben, die den LLVM IR (intermediate
representation) code in Maschinencode für eine bestimmte CPU umwandelt.
Wenn dem so ist, dann wäre so ein integrierter Assembler für das LLVM
machine code (MC) subproject sicherlich eine der sinnvollsten
Zeitinvestition.
Dann durch die vielem LLVM-Frontends hätte man dann gleich noch jede
Menge Untersützung an verschiedensten Programmiersprachen abgedeckt.
Bork schrieb:> Ich denk mir einen Simulator wuerde ich auch noch wollen.
Ja, das hat den grossen Vorteil, dass du in Zukunft Fehler nicht nur in
deinem eigentlichen Code suchen musst, sondern auch im Simulator, das
erhöht die Möglichkeiten dafür, wo ein aktueller Fehler steckt, um
mindestens eine Grössenordnung.
Das ist codevelopment, Nutzprogramm, Assembler und Simulator werden
parallel zu einander debugt.
Georg
georg schrieb:
...
> Das ist codevelopment, Nutzprogramm, Assembler und Simulator werden> parallel zu einander debugt.
...
Boeing führt gerade sehr eindrucksvoll vor, wie sinnvoll das ist.
Na immerhin - wenn er irgendwann fertig ist - kennt er dann den
Prozessor in und auswendig bis aufs letzte Bit und wird Hexdumps ohne
Disassembler zum Frühstück lesen.
R. F. schrieb:> https://de.wikipedia.org/wiki/Sharp_PC-1500
da es ein Zwitter zwischen Z80 und 6502 ist mit etlichen 16 Bit Register
und pi-Takt wäre die Umsetzung echt spannend oder einfach weil beide
Typen 6502&z80 ja schon umgesetzt sind.