Easyrider, 68000 Makro-Assembler

Der Ritt geht weiter...

Nachdem wir in der letzten Ausgabe den Easyrider Reassembler vorgestellt haben, wollen wir Ihnen auch den Makro-Assembler aus der Easyrider-Serie nicht vorenthalten. Es ist ein integriertes System aus tastaturorientierter Benutzeroberfläche. 2-Pass-Makro-Assembler, Linker und Bibliotheksverwalter.

Das Programm, das, wie gesagt, aus Shell, Assembler. Linker und Bibliotheksverwalter besteht, ist mit rund 50 kB angenehm kompakt. Hinzu kommt noch eine Konfigurationsdatei, die die Funktionstastenbelegung beschreibt, sowie ein kleines Utility zur Benutzung der Dateiauswahlbox innerhalb der Shell. Ein Editor wird zur Zeit noch nicht mitgeliefert, doch soll dem nach Möglichkeit abgeholfen werden. Als externer Editor bietet sich TEMPLIS an. mit dem die Shell besonders gut zusammenarbeitet. Ebenfalls im Lieferumfang enthalten sind eine Include-Datei mit Makros für TOS-Funktionen und eine AES-Bibliothek einschließlich deren Quelltext. Das Handbuch ist deutschsprachig und umfaßt 51 Seiten. Easyrider ist nicht kopiergeschützt, aber auf den Anwender installiert (Name und Adresse erscheinen in der Titelzeile).

Anwender, die das Programm bei einem Händler erworben haben, müssen ihre Programmdisketten mit dem Kaufbeleg dem Hersteller zusenden, um am Update-Service teilzunehmen, und erhalten dafür eine auf ihren Namen installierte Version zurück. Zum Test stand die Version 1.10 von Easyrider zur Verfügung. Kurz vor Abschluß dieses Berichts erreichte uns noch die Version 1.12. die teilweise berücksichtigt wurde. Das Programm wurde auf einem ATARI ST mit 1 MB RAM. S/W-Monitor und einer vorläufigen Version des TOS 1.4 im ROM getestet.

Bedienungskonzept

Bei der Bedienung des Assemblers wurde ein ungewöhnlicher Weg eingeschlagen. Nach dem Programmstart präsentiert sich dem Benutzer eine tastaturorientierte Shell, die keinen Gebrauch von GEM macht und nur wenige Befehle kennt, aber ein sehr effizientes Arbeiten ermöglicht. So reicht die Eingabe des Namens eines Quelltextes. um den Assembliervorgang auszulösen, wobei das Programm im allgemeinen auch gleich gelinkt wird. Durch 'RUN: Programmname' läßt es sich anschließend starten. Bei späteren Assemblierversuchen reicht sogar ein simpler Druck auf die RETURN-Taste bzw. ein einfaches RUN:, da Easyrider sich den Namen des letzten Quelltextes sowie des letzten gestarteten Programms merkt. Falls man den Dateinamen nicht kennt, gibt es noch die Möglichkeit mittels einer Dateiauswahl-Box den gewünschten Dateinamen in die Kommandozeile zu kopieren. Ebenfalls mit dem RUN-Kommando läßt sich ein externer Editor aufru-fen. um einen Quelltext erstmals einzugeben oder zu ändern. Daraus folgt schon, daß Easyrider gewöhnliche ASCII-Texte verarbeitet.

Viele Fehlerkorrekturen gestalten sich noch einfacher, da der Assembler bei jedem aufgetretenen Fehler zunächst anhält und die fehlerhafte Zeile anzeigt. Nun kann diese Zeile direkt ediert werden. wobei die Cursor-Tasten. Backspace, Delete und Clr-Home (Zeile löschen) zur Verfügung stehen. Dabei besteht die Möglichkeit, den Fehler nur finden Assemblerlauf zu korrigieren, um weitere (Folge-)Fehler zu verhindern, oder die Änderungen dauerhaft im Quelltext zu sichern. Falls die edierte Zeile nicht länger geworden ist. wird nur sie gesichert (dabei mit Leerzeichen bis zur alten Länge aufgefüllt), ansonsten wird der ganze Quelltext ab der Zeile neu gespeichert, w as bei Benutzung einer RAM-Disk aber kaum einen Unterschied macht. Falls der Fehler nicht durch Korrektur der angezeigten Zeile möglich ist (z.B. weil ein Symbol angesprochen wurde, das an anderer Stelle hätte definiert werden müssen) öderes sich um einen derjenigen (wenigen) Fehler handelt, bei denen eine Korrektur auf diese Weise nicht möglich ist, kann der Fehler übergangen werden, um ihn später (d.h. nach Ende des Assemblerlaufs) zu korrigieren. Auch hier ist Easyrider flexibel. Zum einen kann man einen externen Editor aufrufen und ihm dabei automatisch den Dateinamen und die Zeilennummer des letzten Fehlers übergeben lassen. Dies ist wohl vor allem für TEMPUS gedacht, der dann automatisch den Cursor auf die fehlerhafte Zeile positioniert. Falls einem die direkte Fehlerkorrektur nicht behagt, läßt sie sich mit einer Direktive im Quelltext auch abschalten. Dann läuft der Assembler in einem durch und bricht nur bei fatalen Fehlern ab. Alle nicht korrigierten Fehler merkt sich Easyrider. Sie können später ausgegeben werden. Nachdem der Assembler fertig ist, werden einige Angaben über Fängen der Programm-Segmente, Speicherplatz- und Zeitverbrauch gemacht (s. Bild). Nun befindet man sich im sogenannten “Listing-Generator”, auf den gleich noch nähereingegangen wird. Von hier aus gelangt man per Tastendruck wieder in den Kommandomodus, wo ein neuer Assembliervorgang ausgelöst oder ein externes Programm gestartet werden kann. Zur Shell wäre noch anzumerken, daß meiner Meinung nach die unterschiedliche Behandlung der RETURN- und ENTER-Tasten beim Abschließen einer Eingabezeile eher lästig als hilfreich ist. Bei RETURN werden nämlich alle Zeichen rechts vom Cursor abgeschnitten, nur bei ENTER wird die gesamte Zeile übernommen. Dies scheint mir doch recht gewöhnungsbedürftig. Ebenso muß man bei Benutzung der ESC-Taste ein wenig aufpassen, da man mit ihr stets die jeweilige Programmebene verläßt. Dabei kann es sich um harmlose Aktionen wie das Überspringen einer Fehlermeldung, den Abbruch des Assemblierers aber auch um das Verlassen des Programms handeln. Ein einmal zuviel gedrücktes ESC kann so unerwünschte Folgen haben. Ähnlich verhält es sich mit den unterschiedlichen Bedeutungen von CTRL-C.

Der Eingabe-Komfort wird noch dadurch erhöht, daß die Funktionstasten frei definierbar sind. Dabei stehen auch Platzhalter für den letzten Quelldateinamen sowie die letzte Fehlerzeile zur Verfügung. Außerdem gelangt bei SHIFT + Funktionstaste der definierte Text auch gleich zur Ausführung, ohne SHIFT wird er lediglich in die Eingabezeile kopiert. Aber es kommt noch besser, denn die letzten Eingabezeilen werden in einem I kB großen Puffer gehalten und können mit den Cursor-Tasten zurückgeholt werden.

Dies vereinfacht die Bedienung vor allem dann, wenn mehr als ein Quelltext gleichzeitig bearbeitet wird, da dann der eine Default-Name der Shell nicht ausreicht. Als nachteilig hat sich meines Erachtens das Fehlen sämtlicher Datei-Operationen in der Shell bemerkbar gemacht. Kopieren und Löschen lassen sich noch mit TEMPUS bewerkstelligen, aber beim Umbenennen wird es schon schwierig.

Hier sind entsprechende Accessories, die dann vom GEM-Editor aus aufgerufen werden können, oder eigenständige Utilities, die eigentlich zu UNIX(-Iike)-Shells gehören, hilfreich. Übrigens kann eine Kommandozeile Easyrider schon beim Programmstart als Parameter übergeben werden, doch bietet dies keine nennenswerten Vorteile. Easyrider sollte nämlich nicht in ein TTP-Programm umbenannt werden, da es dann Probleme beim Starten von GEM-Programmen mittels des RUN-Kommandos gibt. Die Benutzung von einem Kommandozeilen-Interpreter aus ist möglich, wird aber nicht besonders unterstützt, da man um die mehrzeile Bildschirmausgabe nach dem Assemblieren und das anschließende Prompt des Listing-Generators nicht herumkommt. Außerdem werden auch keine Standard-Suchpfade oder Environment-Variablen unterstützt. Dies erschwert demnach auch den Einsatz von Programmentwicklungssystemen wie MAKE, aber hier bietet Easyrider selbst einiges (s.u.), was zumindest bei kleineren und mittleren Programmen ausreichend sein dürfte.

Der Listing-Generator

Im Gegensatz zu anderen Assemblern legt man bei Easyrider erst nach dem Assemblieren fest, was man wohin gelistet haben möchte. Deswegen wird, wie oben schon erwähnt, nach dem Assemblerlauf automatisch der sogenannte Listing-Generator aktiviert. Er wird ebenfalls durch Eingabe kurzer Kommandos gesteuert, wobei auch hier ein einfaches RETURN ausreicht, ein komplettes Programmlisting auf dem Bildschirm zu erhalten. Er kann Symboltabellen, Fehlerdateien und Programmlistings ausgeben. Dabei kann die Ausgabe auf den Bildschirm, den Drucker oder in eine Datei erfolgen. Insbesondere werden hierbei mögliche Fehler! Datei schon vorhanden, Drucker nicht empfangsbereit) vernünftig behandelt. Dabei läßt sich das Ausgabeformat noch über zusätzliche im Quelltext stehende Assembler-Direktiven steuern (s.Tab. 1). Es können das Zeilen- und Seitenformat sowie die Tabulator-Breite festgelegt, Zeilen- und Seitenvorschübe eingefügt werden, dem Drucker können beliebige Steuersequenzen übergeben und eine Titelzeile kann spezifiziert werden. Weiterhin gibt es ein “Schmal-Format", bei dem der erzeugte Code nicht mit ausgegeben wird, außerdem läßt sich einstellen, was überhaupt gelistet werden soll: fehlerlose und fehlerhafte Zeilen, Warnmeldungen, Makros (als Makros oder expandiert).

Symbol-Tabelle, dabei sind verschiedene Kombinationen möglich. Das ein/.ige, was vielleicht noch fehlt, ist eine Möglichkeit, das aktuelle Datum irgendwo in der Titelzeile unterzubringen. Nicht so ganz zufriedenstellend funktionierte die Einstellung der Tabulator-Breite. Nach dem “Komprimieren” eines vorher tabulatorfreien Textes mit TEMPUS und Einstellen der gewünschten Breite ergab sich nicht der erwartete Ausdruck. Aber da es sowieso mehrere “Tabulator-Systeme" gibt, kann man es sowieso nicht allen recht machen.


Der Assembliervorgang ist fertig
	BREIT	ERRS	EXP
	LCHAR	LIST	LLEN
	NOLIST	NOEXP	PAGE
	PLEN	SCHMAL	SPACE
	SYMB	TAB		TTL

Tab. 1: Direktiven des Listing-Generators

Der Assembler

Kommen wir nun zum eigentlichen Assembler. Hier zeigt sich Easyrider von einer etwas eigensinnigen Seite, was das Format des Quelltextes angeht. Die Probleme ergeben sich im wesentlichen dadurch, daß Leerzeichen strikt als Trennzeichen zwischen den einzelnen Feldern einer Zeile (Marke, Mnemonic. Operanden. Kommentar) angesehen werden. Marken können mit einem Doppelpunkt beendet werden, jedoch dürfen zwischen der Marke und dem Doppelpunkt keine Leerzeichen stehen, was aber ein beliebtes Mittel zur Verbesserung der Lesbarkeit von Kolonnen von Symbol-Definitionen ist. Ebenso können auch Kommentare durch Leerzeichen abgetrennt werden (neben den üblichen Trennzeichen Stern und Semikolon), was zu fatalen Fehlern führen kann. So wird z.B move.l d0.symbol +4(a0) wegen des Leerzeichens vor dem + zu move.l d0.symbol assembliert, da +4(a0) als “Kommentar" interpretiert wird. Des weiteren dürfen Direktiven nicht mit einem Punkt beginnen. so daß man hier erst einen Editor bemühen muß, um seine alten Quelltexte anzupassen. Nicht nur, daß dies zur Schwierigkeiten bei der Portierung bereits vorhandener Quelltexte führt, sondern es sind auch leicht Fehler bei der Eingabe neuer möglich. Der Assembler ist auch nicht in der Lage, tst.l (a0.d0) zu tsl.l 0(a0,d0) zu ergänzen, wobei dies allerdings eher als Kleinigkeit anzusehen ist. Ansonsten kann man sich aber nicht über die Syntax beklagen. Es werden selbstverständlich alle 68000-Adressierungsarten und Registernamen (einschl. SP.CCR.SR.USP) in der von Motorola festgelegten Syntax akzeptiert. Ebenso ist die Endung .S oder AV zum Festlegen der “Short-Adressierung” zugelassen.

Auch bei den Operatoren in Ausdrücken findet man alles, was man braucht: Grundrechenarten, bitweises AND, OR, XOR, NOT sowie die unären Vorzeichenoperatoren. Die Operatoren sind priorisiert, zusätzlich sind Klammern erlaubt. Es wird grundsätzlich mit 32-Bit-Arithmetik gerechnet. Desweiteren kann auch auf den aktuellen Programmzähler zugegriffen werden. Der Assembler arbeitet im allgemeine tadellos, hat aber anscheinend zumindest einen Fehler. Wenn ‘marke 1 ’ und ‘marke2‘ im Programmtext definierte Marken sind, führt

	LABEL = marke1 - marke2
	moveq #LABEL,d0

zu einer Fehlermeldung, aus der hervorgeht, daß der Assembler LABEL für ein zu relozierendes Symbol hält, was aber nicht der Fall ist. Dagegen funktioniert

	moveq #marke1 - marke2

einwandfrei. Aber damit Iäßt sich noch leben, denke ch.

Direktiven des Assemblers

Ein Assembler soll bekanntlich erlauben, ein Programm auf möglichst bequeme Weise in Assemblersprache zu formulieren. Dazu dienen unter anderem die Direktiven. die ähnlich wie die Mnemonics der eigentlichen Assemblersprache gehandhabt werden Ich möchte hier nur auf die Besonderheiten eingehen, die nicht selbstverständlich sind oder die hier anders als üblich realisiert sind. Eine Übersicht aller Direktiven, die für Assembler (und Linker) relevant sind, zeigt die Tab.2. Easyrider erlaubt die Benutzung lokaler Marken. Sie beginnen mit einem Punkt und ihr Gültigkeitsbereich reicht bis zur nächsten LOCAL-Direktive. Dies ist sicherlich flexibler als die Methode anderer Assembler, bei denen lokale Marken automatisch bei der nächsten globalen Marke ungültig werden, hat aber den Nachteil, daß man - bei extensiver Nutzung lokaler Marken - praktisch jedes Unterprogramm mit einer LOCAL-Direktive beginnen muß. Mit SET definierte Marken dürfen jederzeit umdefiniert werden, im Gegensatz zu den mit EQU oder = definierten. EQUR erlaubt die Benennung von Registern, so daß Register mit symbolischen Bezeichnungen angesprochen werden können. Diese Definitionen lassen sich auch durch die Symbol-Tabelle exportieren. Registerlisten finden MOVEM-Befehl werden nicht unterstützt. ALIGN läßt sich auch zum Justieren des Programmzählers auf Langwort-Adressen verwenden. Da Assemblerprogramme häufig als Ergänzungen zu Hochsprachen-Programmen geschrieben werden, halte ich es für wichtig, daß ein Assembler des Arbeiten mit strukturierten Variablen-Typen erleichtert ('structures' bzw. ’records' für die C- bzw. Pascal-Freunde). Leider bietet Easyrider keine Möglichkeit, solche Strukturen einfach zu definieren (wie etwa mit der ABS-Direktive des MADMAC-Assemblers), sondern es bleibt nur die herkömmliche Methode, alle Komponenten einzeln mit ‘EQLP festzulegen. Ebenfalls für wichtig halte ich die Möglichkeiten eines Assemblers, relative Programmierung zu unterstützen, da dies im allgemeinen Programmcode und Ausfiihrungszeit einsparen hilft. Neben der Code-Optimierung, die unten noch erläutert wird, bietet Easyrider hier die interessante BASE-Direktive. Betrachten wir dazu ein kleines Beispiel:

	text
	lea base5,a5
	clr.l var2(a5)
	bss
	base5:
		var1: ds.w 1
		var2:	ds.l 1

base5 ist dabei zunächst eine normale Marke, ist aber dem Adressregister 5 in der Weise zugeordnet, daß der ‘clr’-Befehl wie ein clr.l var2-base5(a5) assembliert wird. Der integrierte Linker bietet

	ALIGN			BASEn			BSS
	DATA			DC				DCB
	DS				END				EQU, =
	EQUR			EVEN			GLOBL
	IF..ELSE..ENDIF	INCLUDE..END	LOCAL
	MACRO..ENDM		OPT				ORG
	REPEAT..UNTIL	SECTION			SET
	TEXT			XDEF			XREF

Tab. 2: Assembler-Direktiven

noch die Besonderheit, daß er relative Zugriffe (im assemblierten Quelltext!) z.B. vom TEXT ins DATA- oder BSS-Segment zuläßt. Somit ist es also möglich, relativ zu programmieren und trotzdem die saubere Trennung zwischen Programm und Daten beizubehalten. Bei der bedingten Assemblierung mittels IF..ELSE..ENDIF können zwei Ausdrücke miteinander oder ein Ausdruck mit Null verglichen werden, wobei die möglichen Bedingungen EQ, NE, GE, LE, GT und LT sind. Die Ausdrücke dürfen hier sogar Zeichenketten sein. Auch möglich sind Abfragen, ob ein Symbol definiert ist oder ob nicht. Witzig ist die Möglichkeit, quasi eigene Fehlermeldungen zu konstruieren. Z.B. wird bei

	IFEQ A.B
		DIES IST EIN FEHLER

der Text "‘Unbekanntes Befehlswort DIES IST EIN FEHLER" ausgegeben, wenn die Bedingung A=B erfüllt ist. REPEAT..UNT1L arbeitet ähnlich wie IF und dient der Assemblierung sich wiederholender Befehle. Die maximale Verschachtelungstiefe liegt bei 4. Ferner können hiermit Schleifen mit einer testen Zahl von Durchläufen realisiert werden. Kommen wir nun zu den Makros, einem weiteren wichtigen Punkt eines jeden Makro-Assemblers. Es können maximal W Parameter übergeben werden, wobei die Parameter durch \1 bis \99 angesprochen werden. Außerdem kann auf die Extension mittels \0 zugegriffen werden. Der Spezial-Parameter @ expandiert zur laufenden Nummer des Makro-Aufrufs, um für jede Makro Expansion individuelle Marken generieren zu können. Es ist zwar nicht direkt vorgesehen, die Existenz eines Parameters abzufragen, was durchaus nützlich sein kann, aber auf Grund der Arbeitsweise der Ausdrucks-Auswertung ist dies mit einem kleinen Trick (auf den man natürlich erstmal kommen muß) trotzdem möglich. Die Include-Direktive dient neben dem Einfügen von weiteren Quelltexten (Verschachtelung laut Handbuch bis 255 Ebenen tief möglich) auch der Einbindung von Objekt-Dateien und Bibliotheks-Dateien, worauf noch bei der Beschreibung des Linkvorgangs eingegangen wird. Beim Einfügen von Quelltexten wartet Easyrider noch mit einer weiteren Besonderheit auf. Normalerweise lädt Easyrider Include-Dateien speicherresident. d.h. sie werden über beide Durchläufe des Assemblers im Speicher gehalten, sodaß der Assembler effektiv (was die Massenspeicher-Zugriffe angeht) zum 1-Pass-Assembler wird. Dies kann bei mehreren langen Include-Dateien naturgemäß zu Speicherplatzproblemen führen. Daher bietet der Include-Befehl die Option, die einzufügende Datei bei jedem Pass neu lesen zu lassen. Dies ist aber mit der Einschränkung verbunden. daß dann keine Segmentwechsel und Makrodefinitionen in den Include-Dateien erlaubt sind. Dies wird aber wohl nur bei sehr großen Programmen und wenig Speicher notwendig werden, so daß dies keine wesentliche Beschränkung bedeutet.

Code-Optimierung

Nur wenige Assembler nutzen die vielfältigen Möglichkeiten des 68000-Befehlssatzes. den erzeugten Code zu optimieren. Easyrider bildet da leider keine Ausnahme. Die OPT-Direktive erlaubt es. drei Optimierungsmöglichkeiten getrennt ein- und auszuschalten. Dabei handelt es sich um die automatische Umwandlung von "langen Sprüngen" (Bec.W) zu “kurzen" (Bec.S). die Änderung der absoluten Adressierungsarten in die entsprechenden Programmzähler-relativen und der Optimierung der “absolut lang"- zur "absolut kurz"-Adressierung. In den beiden letzten Fällen gilt, daß die Optimierung durch explizite Angabe der Operandengröße (.W bzw .L) verhindert werden kann. Außerdem findet nur Rückwärtsoptimierung statt. Alle anderen Codeverbesserungen einschließlich der Vorwärtsoptimierung bei Verzweigungen muß man also entweder per Hand machen oder bleiben lassen, je nach persönlichem Geschmack. Immerhin werden bei möglichen Vorwärtsoptimierungen Warnmeldungen generiert, die man sich vom Listing-Generator ausgeben lassen kann.

Linken

Normalerweise werden direkt ausführbare Programme erzeugt: mittels einer Option in der Kommandozeile. die den Assemblier Vorgang startet, lassen sich jedoch auch Objekt-Dateien im DR-Format erzeugen. Ebenso läßt sich auf diese Weise verhindern, daß die Objekt-Dateien bzw. Programme überhaupt gespeichert werden. Sollen Objekt-Dateien mit eingebunden werden, so müssen diese im Quelltext mit der "include'-Direktive spezifiziert werden. Eine Angabe über die Kommandozeile ist nicht möglich, daher ist ein wirklich eigenständiges Linken ohne Assemblieren also nicht vorgesehen. Der Linker verarbeitet dabei neben dem DR- auch das GST-Format. so daß das Einbinden fremder Objekt-Dateien möglich ist. Leider hält sich der Assembler beim Erzeugen von Objekt-Dateien nicht ganz an das DR-Objekt-Format. Es wird nämlich nicht für jedes Code-Wort ein Relozierwort erzeugt, sondern am Ende werden Null-Worte weggelassen. Dadurch ist die Relozierdatei im allgemeinen zu kurz. Daher verweigert z.B. TURBO C das Linken einer solchen Datei. Der Linker von LASER C ist da weniger mißtrauisch und ergänzt die fehlenden Daten korrekt mit Null. Für das Assemblieren zu Objekt-Dateien gibt es noch die Direktiven XDEF und XREF. Mit XDEF lassen sich Marken und absolute Bezeichner über die assemblierte Datei hinaus global machen, d.h. andere Objekt-Dateien haben auf Marken nur Zugriff, wenn sie mit XDEF exportiert werden. Anders ausgedrückt, werden mit XDEF deklarierte Marken in die Symbol-Tabelle der Objekt-Datei aufgenommen. Alternativ hierzu können mit einer Form der OPT-Direktive auch alle globalen, relativen Marken pauschal in die Symbol-Tabelle übernommen werden. XREF ist das Gegenstück zu XDEF und erlaubt das Importieren externer Referenzen.

Bibliotheken

Des weiteren ist die Benutzung von DR-Bibliotheken möglich; diese setzen sich aus einzelnen Objekt-Dateien zusammen, von denen nur die tatsächlich benötigten in das Programm eingebunden werden. Dazu existiert ein Bibliotheksverwalter, der ebenfalls direkt in Easyrider integriert ist. Er läßt sich aus der Shell heraus aufrufen und ermöglicht das Anlegen, Löschen. Extrahieren und Überschreiben von Objekt-Dateien ("Moduln") in einer Bibliotheks-Datei. Außerdem kann man sich die Symbol-Tabelle einer Objekt-Datei anzeigen lassen. Dies geschieht menu-gesteuert, d.h., die Objekt-Dateien der Bibliotheks-Datei werden aufgelistet und können mit den Cursor-Tasten ausgewählt werden, und die einzelnen Funktionen können mit den Funktionstasten ausgelöst werden. Das Einfügen und Extrahieren läßt sich auch direkt von der Easyrider-Shell aus bewerkstelligen. Mittels der MODUL-Direktive lassen sich alle Quelltexte einer Bibliothek in einem Quelltext zusammenfassen. Dieser läßt sich mit einem Kommando in die einzelnen Module übersetzen, wobei die Modu-le dann auch gleich automatisch zu einer Bibliotheks-Datei zusammengesetzt werden. Auch die benötigten Bibliotheks-Dateien müssen im Quelltext mit ‘in-clude’ angegeben werden. Da der Assembler beim ‘include’ schon wissen muß, welche Routinen der Bibliothek benötigt werden, muß das ‘include’ allerdings am Ende stehen, was nicht gerade die Übersichtlichkeit des Quelltextes fördert. Abhilfe schafft eine Voraus-Deklaration im Quelltext, was aber wiederum zu mehr Tipparbeit führt. Hier wäre das konventionelle Verfahren, Bibliotheken dem Linker als Parameter zu übergeben, doch vorteilhafter. Es ist ebenfalls möglich, absoluten Code zu erzeugen, d.h. ein reines 68(KK)-Programm ohne GEM-DOS-Programm-Kopf und Relozierdaten. Dazu dient die ORG-Direktive. mit der die absolute Adresse, für die das Programm assembliert werden soll, festgelegt wird.

TOS-Bindings

Beim Schreiben längerer Assembler-Programme wird man zwangsläufig auf die Unterstützung durch das TOS angewiesen sein. Daher stellt sieh die Frage, wie komfortabel TOS-Aufrufe möglich sind. Easyrider bietet eine Include-Datei mit Makros für die BIOS-, XBIOS- und GEMDOS-Funktionen. Diese sind nicht besonders raffiniert (Parameter-Übergabe last immer mit MOVE, manchmal PEA), aber bei der Stack-Korrektur wird immerhin Gebrauch vom ADDQ-Befehl gemacht, wo es möglich ist. Unverständlicherweise fehlen außerdem einige Funktionen (Bioskeys, Prtblk, Blitmode. Super. Tget... Tset... Sversion). Weiterhin gibt es eine AES-Library, die bis auf die neuen Funktionen des TOS 1.4 vollständig ist. Die Bindings sind allerdings sehr umständlich programmiert (sieht aus wie schlecht kompiliertes C). Unterstützung für VDI. LINE A und die Systemvariablen fehlt völlig. Hier gäbe es also noch einiges zu verbessern.

Geschwindigkeit

Ein weiteres Kriterium zur Beurteilung eines Assemblers ist dessen Arbeitsgeschwindigkeit. Auf aufwendige Benchmarks habe ich verzichtet, da ich deren Aussagekraft hier für zweifelhaft halte. Easyrider ist aber auf jeden Fall recht schnell, fixer noch als der MADMAC-Assembler von Atari. Für meinen Geschmack ist er schnell genug, unangenehme Kaffeepausen entstehen nicht. Lim Ihnen dennoch einen genaueren zeitlichen Rahmen zu geben, habe ich einen ca. 50 kB langen Quelltext mit einer 15 bzw. 22 kB (MADMAC bzw. Easyrider) großen Include-Datei assembliert. Auf RAM-Disk benötigte Easyrider 2,9 s, MADMAC dagegen 3,9 s. Bei Diskette lagen die Zeiten bei 13,4 s bzw. 14.6 s. Dabei handelt es sich nur um die Assemblier- und Linkzeiten, die Ladezeit des Assemblers bleibt unberücksichtigt. Die Include-Datei wurde dabei speicherresident geladen. Wie man an den Disketten-Zeiten sieht, ist Easyrider damit quasi ein 1-Pass-Assembler, auch wenn cs intern zwei Durchläufe sind. Da Easyrider im allgemeinen nur einmal geladen werden muß. vergrößert sich sein Vorsprung damit nochmals. Ebenso spart das direkte Korrigieren vieler Fehler oftmals das Laden des Editors, was die Turn-around-Zeit weiter senkt. Bei dieser Gelegenheit sollte auch einmal die Betriebssicherheit hervorgehoben werden. Bei mir gab es in der Testphase keinen einzigen Absturz oder irgendwelche anderen Ungereimtheiten, die keine "natürliche" Ursache hatten.

Handbuch

Das Handbuch bietet einen Schnellkursus für Lesefaule, der dem erfahrenen Programmierer ein sofortiges Arbeiten ermöglicht. Die Anleitung bietet alle wesentlichen Informationen und läßt kaum Fragen offen, die eist durch Ausprobieren beantwortet werden müssen. Die Formulierungen sind knapp aber präzise. Beispiele ergänzen die Erklärung. Wichtige Passagen sind durch Fettdruck hervorgehoben. Ebenso werden Spezialfalle und Klippen ausreichend behandelt. Vorausgesetzt werden Kenntnisse des 68000-Assemblers. da der Befehlssatz und die Adressierungsarten nur tabellarisch aufgelistet sind. Einzig die Gliederung ist manchmal etwas merkwürdig, so sind die Möglichkeiten der Shell über mehrere Kapitel verstreut. Hier wäre eine Zusammenfassung der Kommandozeilen-Svn-tax, Assembler-Aufrufmöglichkeiten und Editierfunktionen angebracht. Die Liste der Fehlermeldungen ist unsortiert, so daß man ein wenig suchen muß. Außerdem wäre es für Anfänger sicher hilfreich, wenn hier bei allen Meldungen einige Tips zur Behebung des Fehlers stünden.

Fazit

Zusammengenommen läßt sich urteilen, daß man mit Easyrider ein leicht und effizient zu bedienendes Assembler-System in der Hand hält. Der Assembler ist allerdings beim Format der Quelltexte zu pingelig oder großzügig (wie man’s nimmt), was das Portieren vorhandener Quelltexte erschwert und Fehler begünstigt. Der Assembler bietet die wichtigsten Direktiven und ein paar komfortable darüber hinaus (BASEn, EQUR. LOCAL), erfüllt aber nicht alle Wünsche, die man als Assembler- und Hochsprachen-Programmierer so hat (aber welcher ST-Assembler tut das schon - ich kenne jedenfalls keinen). Die Ausgabemöglichkeiten sind vielseitig, das ganze System ist schnell und betriebssicher. Modulare und relative Programmierung werden gut unterstützt. Der Linker und insbesondere die TOS-Unterstützung sind noch verbesserungsbedürftig. Auch die Code-Optimierungen sind nicht gerade berauschend. Das Handbuch halte ich für gut und vollkommen ausreichend. Insgesamt ragt Easyrider zwar nicht besonders aus allen anderen Assemblern heraus, kann aber durchaus mit anderen Systemen mithalten und sollte daher einer näheren Betrachtung wert sein.

Easyrider Assembler
Einzelpreis DM 59,-
Paketpreis (mit Reassembler) DM 198.-
Update-Gebühr DM 10.- für registrierte User



Aus: ST-Computer 10 / 1989, Seite 61

Links

Copyright-Bestimmungen: siehe Über diese Seite