amiga-news ENGLISH VERSION
.
Links| Forum| Kommentare| News melden
.
Chat| Umfragen| Newsticker| Archiv
.

amiga-news.de Forum > Programmierung > Assembler/Includes: "unknown mnemonic <funcdef>" [ - Suche - Neue Beiträge - Registrieren - Login - ]

-1- [ - Beitrag schreiben - ]

19.03.2015, 18:26 Uhr

cgutjahr
Posts: 2779
[Administrator]
Ich versuche etwas m68k-Code mit vasm unter Linux zu assemblieren, das ist mein allererster ASM-Gehversuch auf dem Amiga - bin sonst eher 6502-Fan ;)

Der Code beginnt wie folgt (im unter incdir angegebenen Verzeichnis liegt das offizielle 3.9 NDK):

code:
section Bashii,CODE
OPT C-,D+	
opt NODEBUG
opt p=68000 		

incdir	"/home/christoph/Temp/NDK_3.9/Include/include_i/"
include "exec/exec_lib.i"


Der Assembler beschwert sich allerdings:

code:
$ ./vasm main.s
vasm 1.4d (c) in 2002-2009 Volker Barthelmann
vasm M68k/CPU32/ColdFire cpu backend 1.1f (c) 2002-2009 Frank Wille
vasm motorola syntax module 3.1 (c) 2002-2009 Frank Wille
vasm test output module 1.0 (c) 2002 Volker Barthelmann

error 2 in line 12 of "exec/exec_lib.i": unknown mnemonic <funcdef>
included from line 32 of "main.s"

Was mache ich falsch?

[ - Antworten - Zitieren - Direktlink - ]

19.03.2015, 19:06 Uhr

cgutjahr
Posts: 2779
[Administrator]
Geit hat mir weiter geholfen: im 3.9 NDK ist das Macro "FUNDEF" definiert, allerdings ist die Definition in exec/libraries.i auskommentiert. include ich diese Datei und entferne die Asterisks vor der Makro-Definition, kriege ich gleich die nächste Fehlermeldung - merkwürdig.

Geit hat mir eine ältere Version von exec/exec.i geschickt, die statt irgendwelche Makros zu verwenden einfach direkt diverse Werte zuweist, Jetzt läuft zumindest der Assembler durch,

Allerdings nur bis zu dieser Fehlermeldung:

code:
fatal error 2035 in line 246 of "glens_code/bullet_hit_routines.s": illegal opcode extension
included from line 549 of "main.s"


Zeile 246 von bullet_hit-routines.s" sieht so aus:

code:
moveq.w	#1,d2
bsr	Change_Block


[ - Antworten - Zitieren - Direktlink - ]

19.03.2015, 19:19 Uhr

Thore
Posts: 2266
Nutzer
"Falsch" ist nicht das richtige Wort, dein Assembler kennt nur nicht das Macro "funcdef".
Um zu verstehen, was falsch ist, muss ich bisschen ausholen, wenn Du das nicht wissen willst, les einfach den letzten Abschnitt.

Zunächst einmal der Hinweis, dass incdir, include und funcdef keine Assembler-Befehle sind sondern Direktiven, die für das Assembler-Programm (vasm, a68k, phxass,...) sind. Sie erzeugen keine Opcodes.

funcdef ist ein Macro einer einfachen Wertezuweisung.
Es ersetzt den angegebenen Namen durch ein _LVO<Name> = -<Offset>

Eine LVO ist ein Lib-Vector-Offset. Üblicherweise sind sie negativ und fangen üblicherweise bei -30 an, und machen dann 6er Schritte. Jede Library hat seine eigene Offset Tabelle. Jede Lib-Funktion wird in dieser Tabelle addressiert.

Beispiel für die Exec Lib, bei Dir sieht das so aus:
FUNCDEF Supervisor
FUNCDEF ExitIntr
FUNCDEF Schedule

Wenn das Macro ausgeführt wird, sieht das so aus:
_LVOSupervisor EQU -30
_LVOExitIntr EQU -36
_LVOSchedule EQU -42

Das zugehörige Macro wird in exec/funcdef.i definiert:

FUNCDEF MACRO *function
_LVO\1 EQU FUNC_CNT
FUNC_CNT SET FUNC_CNT-6
ENDM
FUNC_CNT SET 5*-6

Also einfach exec/funcdef.i rein-includen oder Macro definieren (dann aber nicht vergessen, FUNC_CNT am Anfang auf -30 zu setzen)

[ - Antworten - Zitieren - Direktlink - ]

19.03.2015, 19:21 Uhr

Thore
Posts: 2266
Nutzer
moveq kann nicht Word-weise kopieren, sondern nur Byteweise. Daher funktioniert hier das ".w" nicht. Lass das .w einfach weg.

[ - Antworten - Zitieren - Direktlink - ]

19.03.2015, 22:24 Uhr

cgutjahr
Posts: 2779
[Administrator]
Zitat:
Original von Thore:
"Falsch" ist nicht das richtige Wort, dein Assembler kennt nur nicht das Macro "funcdef".

Vielen Dank für die ausführliche Antwort. Was Macros sind, ist mir schon klar, ich habe wie gesagt durchaus Erfahrung mit Assemblern und Compilern.

Zitat:
Das zugehörige Macro wird in exec/funcdef.i definiert:
ein funcdef.i existiert bei mir nicht. Ich hatte heute Mittag bereits mit grep gesucht, das liefert nur Treffer in exec/exec_lib.i (dort wird das Macro benutzt) und in exec/libraries.i, wo es definiert wird - dort ist es allerdings auskommentiert:

code:
*------ FUNCDEF is used to parse library offset tables.  Many applications
*------ need a special version of FUNCDEF - you provide your own macro
*------ to match your needs.  Here is an example:
*
*	FUNCDEF		 MACRO
*	_LVO\1		 EQU	FUNC_CNT
*	FUNC_CNT	 SET	FUNC_CNT-6	* Standard offset-6 bytes each
*	FUNC_CNT	 EQU	LIB_USERDEF	* Skip 4 standard vectors
*			 ENDM

Ist vielleicht das NDK auf os.amigaworld.de lückenhaft? Es macht ja keinen Sinn, Includes zu verteilen die jeder erstmal noch selbst reparieren oder vervollständigen muss...

Aber wie gesagt, mit Geits exec_lib.i funktioniert es erstmal.

Zitat:
moveq kann nicht Word-weise kopieren, sondern nur Byteweise. Daher funktioniert hier das ".w" nicht. Lass das .w einfach weg.
Ah, danke! Allerdings gibt's den Fall jetzt 70 Mal über sämtliche Codeteile verstreut - werde wohl eine Weile beschäftigt sein ;)

Scheinbar kümmert Devpac sich nicht um solche Kleinigkeiten und assembliert einfach weiter. Merkwürdiges Verhalten...

[ - Antworten - Zitieren - Direktlink - ]

19.03.2015, 22:59 Uhr

cgutjahr
Posts: 2779
[Administrator]
Hm, bin gerade dabei die zahlreichen Fehler zu beseitigen, die der Assembler meldet. Das hier verstehe ich nicht:

code:
error 2029 in line 1602 of "glens_code/alien_intelligence.s": branch destination out of range
included from line 560 of "main.s"


Zeile 1601ff sehen so aus:

code:
tst.w	Wind_Change
    beq.s	Dont_Change_Speed
Dont_Change_Speed	
    cmp.w	#6,Wind_Counter
    bge.s	No_Need_To_Slow_Wind

Mal abgesehen davon, dass der Code so keinen Sinn macht: ich gehe mal davon aus, dass beq.s für "branch on equal.short" steht - wie um Himmels willen kann das "out of range" sein?

[ - Antworten - Zitieren - Direktlink - ]

20.03.2015, 08:31 Uhr

thomas
Posts: 7716
Nutzer
@cgutjahr:

Ein normaler Branch hat einen 16bit-Offset von der aktuellen Position zum Sprungziel. Mit .s verkürzt sich der Offset auf 8 Bits. D.h. dein Sprungziel (vermutlich No_Need_To_Slow_Wind) ist weiter als +127 bzw -128 Bytes von der aktuellen Position im Code entfernt.


--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]

20.03.2015, 14:13 Uhr

cgutjahr
Posts: 2779
[Administrator]
Zitat:
Original von thomas:
D.h. dein Sprungziel (vermutlich No_Need_To_Slow_Wind) ist weiter als +127 bzw -128 Bytes von der aktuellen Position im Code entfernt.

Ja, so hatte ich beq.s interpretiert. Aber die vom Compiler monierte Zeile 1602 ist das hier:

code:
beq.s	Dont_Change_Speed

und das Sprungziel folgt direkt eine Zeile darunter... Der String "Dont_Change_Speed" taucht laut grep im ganzen Tree nur in diesem Dokument, in den beiden direkt aufeinander folgenden Zeilen auf.

[ - Antworten - Zitieren - Direktlink - ]

20.03.2015, 14:45 Uhr

thomas
Posts: 7716
Nutzer

Vielleicht wird der Spezialfall Offset=0 von vasm nicht korrekt behandelt. Oder Offset=0 ist tatsächlich ungültig. So gut kenne ich mich mit den 68k-Feinheiten nicht aus.


--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]

20.03.2015, 18:51 Uhr

jolo
Posts: 110
Nutzer
Ist illegal. Wird trotzdem von manchen Assemblern auf Source-Code-Basis akzeptiert, jedoch beim Übersetzen in ein "NOP" gewandelt.

[ - Antworten - Zitieren - Direktlink - ]

21.03.2015, 15:59 Uhr

cgutjahr
Posts: 2779
[Administrator]
Bingo! Der Offset war das Problem, ich hab die drei Stellen auskommentiert und ein einwandfrei funktionierendes Binary assembliert :D Herzlichen Dank euch allen.

Allerdings würde mich schon noch interessieren, was es mit dem 3.9 NDK auf sich hat - es kann ja nicht sein, dass die Includes im AUslieferungszustand erstmal nicht benutzbar sind - also entweder habe ich einen Schritt übersehen, oder irgendetwas stimmt mit dem Archiv nicht, oder?


[ - Antworten - Zitieren - Direktlink - ]

21.03.2015, 17:33 Uhr

Thore
Posts: 2266
Nutzer
Die Includes sind benutzbar für die meisten Compiler bzw Assemblierer (ich benutz nun das Wort Assemblierer, um Verwirrung mit "Assembler" an sich zu vermeiden)
Der vasm hat ein paar Eigenheiten, die eben die anderen nicht haben. Dafür sind andere etwas zu tolerant in Fehler, wobei man sich schlechte Dinge angewöhnen kann.
Die Includes können daher auch nicht für alle gerecht gemacht werden, schon allein weil es den vasm so noch nicht gab, als die erstellt wurden.
Auf a68k, phxass und anderen damaligen Standard Assemblern hatte ich nie Probleme.

[ - Antworten - Zitieren - Direktlink - ]

21.03.2015, 20:15 Uhr

jolo
Posts: 110
Nutzer
Zu jedem kommerziellen Assembler damaliger Zeit wurden die passenden, sprich Assembler spezifischen LVO-Dateien ("nnn/nnn_lib.i") mitgeliefert, und die Datei "funcdef.i" geflissentlich ignoriert (anbei, diese Datei ist sowieso Assembler spezifisch und eigentlich nur für "exec/exec_lib.i" erdacht). Liegt darin begründet, dass LVOs nicht zwingend aneinanderhängend in der passsenden "FD"-Datei (also der Beschreibungsdatei zu einer Shared-Bibliothek) angegeben werden müssen, sondern ein Schlüsselwort Verwendung finden kann, um einen privaten Library-Vector-Offset zu deklarieren, der keinen gültigen Namen hat. Zudem kann man in den neueren (1991?) "SFD"-Dateien auch Einträge komplett übergehen, die damit dann gänzlich ohne Bezeichner sind.
Da das Makro FUNCDEF aber zwingend reguläre Bezeichner braucht, jedoch private Bezeichner ungültig und unschön sind, ist das FUNCDEF-Makro nicht wirklich passend. Zudem kostet das FUNCDEF-Makro Zeit, um die entsprechenden Offsets zu berechnen, so dass man sich auch noch aus Geschwindigkeitsgründen dafür entschieden hat, direkt die LVOs anzugeben ohne den Umweg über das FUNCDEF-Makro zu nehmen.
Zudem waren die von Commodore Amiga publizierten SDKs nicht für alle verfügbaren Assembler passend und mussten dementsprechend sowieso nachgebessert werden, warum also nicht gleich die LVOs direkt hinein schreiben?

Zusammenfassung:
"funcdef.i" ist Assembler spezifisch.
"funcdef.i" ist nur erdacht für "exec/exec_lib.i", die anderen LVOs sollten nach Willen von Commodore Amiga beim Linken der "amiga.lib" entnommen werden.
"funcdef.i" ist unschön, weil private Bezeichner Verwendung finden.
"funcdef.i" ist zeitaufwändig, weil Berechnungen durchgeführt werden müssen.

Gegenmaßnahme:
Ersatzlos streichen und aus der Devpac-Entwicklungsumgebung die "nnn/nnn_lib.i"-Dateien klauen. :-)

[ - Antworten - Zitieren - Direktlink - ]

21.03.2015, 20:44 Uhr

Thore
Posts: 2266
Nutzer
Jupp schließ ich mich an. Die Funcdefs waren ein Versuch, die _LVO Equations zu vereinfachen. Aber stattdessen verwirrts nur ;) Ich include übrigens nur bei größeren Projekten. Bei kleineren schreib ich die LVOs raus, das assembliert schneller und es bleibt übersichtlich. Oft schreib ich auch das Offset direkt in den Code rein und mach ein Kommentar, welche Funktion es ist, z.B.:
move.l $4,a6
lea dosname(pc),a1
jsr -408(a6) ; Open Lib
tst.l d0
beq .errordos
move.l d0,dosbase
...

[ - Antworten - Zitieren - Direktlink - ]

23.03.2015, 16:16 Uhr

woop
Posts: 67
Nutzer
Ich bevorzuge die Methode die LVOs aus der amiga.lib oder der small.lib zu linken:

code:
XREF	_LVOGetMsg

doSomething:
	[...]
	; use exec.library
	movea.l	_SysBase,a6
	jsr	_LVOGetMsg(a6)
	[...]

	end


Nachteile:
* Man muss immer linken
* zusätzliche XREF-Zeile für jede verwendete Funktion

Vorteile:
* Im Sinne der Erfinder
* Zusätzliche Linkzeiten fallen schon auf kleineren Systemen kaum ins Gewicht
* sehr kompatibel unter den verschiedenen Assemblern
* keine Fehler durch verwechselte oder falsche Offsets

[ - Antworten - Zitieren - Direktlink - ]

24.03.2015, 10:50 Uhr

geit
Posts: 332
[Ex-Mitglied]

Ich habe damals Jahrelang mit DevPac programmiert und mir mit List LFormat einen Quellkode erstellt, der alle header includiert. Diese header habe ich dann einmalig zu einem Headerklumpen assembliert.

Den habe ich dann einfach in den Settings eingetragen und brauchte in meinen Quellen weder etwas includen noch etwas einfügen.

Das Assemblieren dauerte immer gleich lang (1 Sekunde oder so für das Laden der Header), weil nicht ständig nach den selben Dateien auf der Platte gesucht wurde und nur einmal 370 KB (OS3) bis 470 KB (OS3.9) geladen wurden.

Man kann keine includes vergessen und wenn ein Fehler auftritt hat man sich vertippt und nicht ein include vergessen.

Das habe ich für jede OS Version der includes gemacht, um einfach wechseln zu können, wenn ich spezielle Versionen für ältere Systeme gebaut habe,

[ - Antworten - Zitieren - Direktlink - ]

24.03.2015, 16:33 Uhr

Holger
Posts: 8116
Nutzer
@geit:
Das war ja die Spezialität des DevPac, die header in eine vorübersetzte Form bringen zu können (.gs files, wenn ich mich richtig erinnere). Da hat das Einbinden sämtlicher Header deutlich weniger als eine Sekunde gedauert.

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]


-1- [ - Beitrag schreiben - ]


amiga-news.de Forum > Programmierung > Assembler/Includes: "unknown mnemonic <funcdef>" [ - Suche - Neue Beiträge - Registrieren - Login - ]


.
Impressum | Datenschutzerklärung | Netiquette | Werbung | Kontakt
Copyright © 1998-2024 by amiga-news.de - alle Rechte vorbehalten.
.