Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Die Delphi-IDE (https://www.delphipraxis.net/62-die-delphi-ide/)
-   -   Assembler Files einbinden (https://www.delphipraxis.net/144506-assembler-files-einbinden.html)

FrEEzE2046 9. Dez 2009 10:23


Assembler Files einbinden
 
Hallo,

ich suche eine Möglichkeit reinen Assembler Code in Delphi zu verwenden.

Soll heißen:
Ich habe mehrere reine Assembler Dateien, die verschiedene Routinen enthalten, die ich in Delphi nutzen möchte. Prinzipiell muss ich nur eine Möglichkeit haben die asm-files zu kompilieren (ggf. eben mit nasm) und dem Delphi-Linker mitzuteilen, dass ich ein paar externe Procedures und Functions habe.

Dass das möglich ist zeigt Delphi selbst in der system.pas (zu finden unter "...\Borland\Delphi5\Source\Rtl\Sys\") wo verschiedene assembler funktionen als extern deklariert wurden.


Wie genau muss ich da vorgehen? Ich bin ein C/C++ Mensch und verwende Delphi nur in der Not. Wäre wirklich super, wenn jemand die Lösung hätte.

himitsu 9. Dez 2009 11:08

Re: Assembler Files einbinden
 
du kannst es direkt als "Inline-ASM" anlegen

das geht an jeder Stelle innerhalb des Pascalcodes oder auch als kompletter Prozedurrumpf.
Delphi-Quellcode:
asm
  mov eax, 0
end;
wenn du reine ASM-Befehle im "Delphi-Stiel" einbinden willst
Delphi-Quellcode:
asm
  {$INLINE myfile.asm}
end;

FrEEzE2046 9. Dez 2009 11:49

Re: Assembler Files einbinden
 
Zitat:

Zitat von himitsu
du kannst es direkt als "Inline-ASM" anlegen

Danke für deine Hilfe. Ich habe aber extra "reines asm" geschrieben, da ich den Inline-Assembler eben NICHT benutzen will.
Dass die Möglichkeit besteht, zeigt - wie bereits erwähnt - die System.pas.

Irgendwie muss das doch möglich sein, dem Linker mitzuteilen, dass da was existiert. Wenn ich die Funktion per extern kennzeichne und den Pfad zu einer aout datei setzte, dann kommt die Fehlermeldung, dass die datei keine "Windowsdatei" wäre ...

Muetze1 9. Dez 2009 12:11

Re: Assembler Files einbinden
 
Übersetzen mit TASM und in Delphi einbinden per Schlüsselwort "external" und dem Befehl die OBJ dazu zu linken "{$L file.obj}"

uligerhardt 9. Dez 2009 12:15

Re: Assembler Files einbinden
 
Schuss ins Blaue: *.asm in *.obj kompilieren und in einer Delphi-Unit {$L Funktionen.obj}. Sowas Ähnliches wird in ZLib.pas (in den VCL-Sourcen, zumindest bei mir (D2007)) gemacht.

@Roter Kasten: Ich hab ja noch den Verweis auf ZLib als Beispiel. :-)

gammatester 9. Dez 2009 12:18

Re: Assembler Files einbinden
 
Zitat:

Zitat von FrEEzE2046
Danke für deine Hilfe. Ich habe aber extra "reines asm" geschrieben, da ich den Inline-Assembler eben NICHT benutzen will.
Dass die Möglichkeit besteht, zeigt - wie bereits erwähnt - die System.pas.

Irgendwie muss das doch möglich sein, dem Linker mitzuteilen, dass da was existiert. Wenn ich die Funktion per extern kennzeichne und den Pfad zu einer aout datei setzte, dann kommt die Fehlermeldung, dass die datei keine "Windowsdatei" wäre ...

Das ist Unsinn: System.pas bindet kein reines asm ein. Was gemacht wird - und schon seit dem letzen Jahrtausend unterstützt wird-, ist das Einbinden von Obj-Files. Wo die herkommen ist im Prinzip egal, Du kannst zB ASM-Files mit TASM oder MASM übersetzen.

himitsu 9. Dez 2009 12:32

Re: Assembler Files einbinden
 
Der Delphi-Compiler kennt nur sein Pascal, das sogenannte "Inline"-ASM und den vorkompilierten Maschienencode aus OBJ-Dateien.

Wenn du ihm etwas Anderes mitgeben willst, dann mußt du dieses erstmal in ein Format bringen, welches der Delphi-Compiler kennt.
Also, indem man z.B. Assembler via TASM oder MASM oder C über einen C-Compiler in das OBJ-Format umwandelt.

FrEEzE2046 9. Dez 2009 13:02

Re: Assembler Files einbinden
 
Zitat:

Zitat von gammatester
Das ist Unsinn: System.pas bindet kein reines asm ein. Was gemacht wird - und schon seit dem letzen Jahrtausend unterstützt wird-, ist das Einbinden von Obj-Files. Wo die herkommen ist im Prinzip egal, Du kannst zB ASM-Files mit TASM oder MASM übersetzen.

Ich wollte auch nicht sagen, dass der Delphi-Compiler Assembler kompilieren kann. Die Antwort, eine Obj.-Datei per extern einzubinden, war die die ich wollte. Ich meinte eigentlich auch lediglich, dass System.pas auch externe (ursprünglich in assembler geschriebene) Routinen einbindet.

FrEEzE2046 9. Dez 2009 13:12

Re: Assembler Files einbinden
 
Ich bekomms einfach nicht hin:

Hab mal ein Test-Szenario erstellt. Sieht folgendermaßen aus:


Delphi-Quellcode:
unit TestUnit;

interface

   function Summe(i1, i2 : Integer): Integer;

implementation

   function Summe(i1, i2 : Integer): Integer; external; {$L sum.obj}

end.

Code:
global _Summe

; function Summe(i1, i2: Integer): Integer ;
_Summe:
  add eax, edx
  ret

Ich habe "sum.obj" folgendermaßen kompiliert:
nasmw -f obj -o sum.obj
nasmw -f win32 -o sum.obj


Ich bekomme die Meldung, dass sum.obj ein falsches Dateiformat wäre (win32) bzw. 16-Bit Segmente entdeckt wurden (obj)


Was mache ich falsch?

gammatester 9. Dez 2009 13:46

Re: Assembler Files einbinden
 
Wenn sum.asm Dein Beispiel wie folgt enthält
Code:
.586
.model flat
.code
public sum
sum proc
    add eax,edx
    ret
sum endp
    end
mit Tasm32 assemblieren: Tasm32 sum.asm und einbinden mit
Delphi-Quellcode:
function sum(a,b: integer):integer; register; external; {$l sum.obj}
Läuft ohne Probleme.

Ansonsten Aufrufkonventionen beachten/anpassen: stdcall, pascal, cdecl Stichwort Calling conventions in Onlinehilfe.

FrEEzE2046 9. Dez 2009 13:53

Re: Assembler Files einbinden
 
Zitat:

Zitat von gammatester
Ansonsten Aufrufkonventionen beachten/anpassen: stdcall, pascal, cdecl Stichwort Calling conventions in Onlinehilfe.

Die Aufrufkonventionen kenne ich. Müsste bei mir natürlich register sein, ist es aber sowieso by default.
Mein Problem ist, dass er mein object-file anmeckert, weil es angeblich 16 Bit Segmente enthält.

gammatester 9. Dez 2009 14:04

Re: Assembler Files einbinden
 
Das ist dann aber hauptsächlich ein NASM-Problem; vielleicht gibt's da ja ein Forum, wo Du nachfragen kannst.

Fridolin Walther 9. Dez 2009 14:13

Re: Assembler Files einbinden
 
Du solltest auch darauf achten, daß es durchaus unterschiedliche Object Dateiformate gibt. Die zwei gängigsten Formate sind OMF und COFF. Delphi versteht dabei nur OMF. Die meisten anderen Entwicklungstools wie z.B. Visual Studio benutzen das COFF Format. Da die von NASM erzeugten Objektdateien in Visual Studio nutzbar sind, würde ich vermuten, daß es COFF Dateien erzeugt. Ob NASM evtl. auch OMF Dateien erzeugen kann, kann ich nicht sagen (aber ein Blick in die Hilfe sollte helfen). Ansonsten solltest Du einen Assembler verwenden, der OMF Dateien erstellen kann, wie z.B. der bereits genannte TASM32.

FrEEzE2046 9. Dez 2009 14:14

Re: Assembler Files einbinden
 
Okay, mit MASM kompiliert und schon geht's. Irgendwie kann NASM(W) keine 32-Bit OMF-OBJ Dateien erzeugen ... okay, dann danke an alle.

FrEEzE2046 9. Dez 2009 14:16

Re: Assembler Files einbinden
 
Zitat:

Zitat von Fridolin Walther
Du solltest auch darauf achten, daß es durchaus unterschiedliche Object Dateiformate gibt. Die zwei gängigsten Formate sind OMF und COFF. Delphi versteht dabei nur OMF. Die meisten anderen Entwicklungstools wie z.B. Visual Studio benutzen das COFF Format. Da die von NASM erzeugten Objektdateien in Visual Studio nutzbar sind, würde ich vermuten, daß es COFF Dateien erzeugt. Ob NASM evtl. auch OMF Dateien erzeugen kann, kann ich nicht sagen (aber ein Blick in die Hilfe sollte helfen). Ansonsten solltest Du einen Assembler verwenden, der OMF Dateien erstellen kann, wie z.B. der bereits genannte TASM32.

NASM kann COFF Objektdateien erzeugen, ja. Aber mit dem Compiler-Parameter obj erzeugt man OMF. Ganz sicher, steht auch so in der Command-Line-Hilfe (-hf).

Fridolin Walther 9. Dez 2009 14:17

Re: Assembler Files einbinden
 
Ich kenn NASM nicht. Benutze persönlich MASM oder TASM32. War nur eine Vermutung meinerseits.

gammatester 9. Dez 2009 14:35

Re: Assembler Files einbinden
 
Da Du bei nasm/obj eine "16-Bit Segment"-Fehlermeldung erhälst, fehlt vielleicht eine 32-Bit directive, zB etwas wie section .text use32 (aus einem alten aes.asm, habe keine Ahnung von nasm).

Gruß Gammatester

Neutral General 9. Dez 2009 14:49

Re: Assembler Files einbinden
 
versuche mal bei NASM

Delphi-Quellcode:
[BITS 32]
; Code...

FrEEzE2046 14. Dez 2009 12:11

Re: Assembler Files einbinden
 
Zitat:

Zitat von Neutral General
versuche mal bei NASM
Delphi-Quellcode:
[BITS 32]
; Code...

Danke für deine Hilfe, aber das war natürlich das erste was ich gemacht hatte. Ich kann leider nicht sagen wo ran es liegt.

Dummerweiße zwingt mich dass jetzt dazu MASM zu benutzen und ich stoße dabei auf einige Probleme. Ich habe folgenden Code:

Code:
TITLE SimpleTest.asm
 
.686P
.XMM
.MODEL FLAT


PUBLIC Proc1
PUBLIC Proc2


.CODE

Proc1 PROC
   ; ;
Proc1 ENDP

Proc2 PROC
   ; ;
Proc2 ENDP

END

In Delphi sind Proc1 und Proc2 mt 'external' deklariert und linken das entsprechende Obj-File. So lange ich nur Proc1 (oder Proc2) kompiliere und in Delphi einbinde, habe ich keine Probleme.
Wenn ich aber zwei Routinen (also Proc1 und Proc2) kompiliere und dann entsprechend in Delphi deklariere, bekomme ich die Fehlermeldungen:

Code:
Falsche globale Symboldefinition in [...] (Objfile)
Ungenügende external Deklaration Proc1

Was genau hat sich dadurch geändert, dass ich noch eine zweite Funktion in meinem Code habe? Also MASM wirft da keine Fehler, aber Delphi mag es nicht mehr. Kompiliert habe ich es mit /omf.

FrEEzE2046 14. Dez 2009 13:55

Re: Assembler Files einbinden
 
Dazu sollte man noch sagen, dass der selbige Code (mit angepasster Parameterabfrage) sich ohne Probleme in C (VC 9) verwenden lässt.

gammatester 14. Dez 2009 13:58

Re: Assembler Files einbinden
 
Falls es hilft: Keine Probleme mit TASM 5.0.

gammatester 14. Dez 2009 14:05

Re: Assembler Files einbinden
 
Hier eine Version mit MASM, die ohne Probleme von D6 akzeptiert wird.
Code:
TITLE SimpleTest.asm
 
.686P
.XMM
.MODEL FLAT

PUBLIC Proc1
PUBLIC Proc2

.CODE proc1_text
Proc1 PROC
   ; ;
Proc1 ENDP

.CODE proc2_text
Proc2 PROC
   ; ;
Proc2 ENDP

END

FrEEzE2046 14. Dez 2009 14:08

Re: Assembler Files einbinden
 
Zitat:

Zitat von gammatester
Falls es hilft: Keine Probleme mit TASM 5.0.

Ich hab auch kein Probleme mit MASM. Das Problem ist (vermutlich) die Deklaration in Delphi. Sieht bei mir so aus:

Code:
TITLE Test.asm
 
.686P
.XMM
.MODEL FLAT


PUBLIC Proc1
PUBLIC Proc2


.CODE

Proc1 PROC
   ret
Proc1 ENDP

Proc2 PROC
   ret
Proc2 ENDP

END

Delphi-Quellcode:
Unit Test;

interface

procedure Proc1();
procedure Proc2();

implementation

{$LINK Test.obj}

procedure Proc1(); external;
procedure Proc2(); external;

end.

Wenn ich Proc2 in Delphi auskommentiere, dann geht es. Lasse ich es drin:
Code:
Ungenügende Forward- oder External-Deklaration 'Proc2'

Und in C mit dem VS geht das wunderbar. Versteh ich absolut nicht, was da die Ursache ist.


Zitat:

Zitat von gammatester
Hier eine Version mit MASM, die ohne Probleme von D6 akzeptiert wird.

Ich hab Delphi 5. Es liegt nicht an MASM.

gammatester 14. Dez 2009 14:32

Re: Assembler Files einbinden
 
Meine letzte Version mit .CODE proc2_text ist auch mit Delphi5 kompilierbar. Daß es D5 bei Dir nicht packt, liegt dann wohl daran, daß Du nicht das letzte asm benutzt oder geht's damit auch nicht?

FrEEzE2046 14. Dez 2009 14:35

Re: Assembler Files einbinden
 
Zitat:

Zitat von gammatester
Meine letzte Version mit .CODE proc2_text ist auch mit Delphi5 kompilierbar. Daß es D5 bei Dir nicht packt, liegt dann wohl daran, daß Du nicht das letzte asm benutzt oder geht's damit auch nicht?

Was meinst du mit "das letzte ASM"?
Ich benutze den Code, der in meinem letzten Posting steht. Wie hast du es denn in Delphi deklariert?

gammatester 14. Dez 2009 14:40

Re: Assembler Files einbinden
 
Zitat:

Zitat von FrEEzE2046
Was meinst du mit "das letzte ASM"?
Ich benutze den Code, der in meinem letzten Posting steht. Wie hast du es denn in Delphi deklariert?

Na ja, daß mit dem es klappt aus #22. Deklaration in D5 (die asm/obj-Files heißen bei mit xx.asm und xx.obj, erzeugt mit ml /c XX.ASM)
Delphi-Quellcode:
procedure proc1; external;
procedure proc2; external;
{$link xx.obj}

FrEEzE2046 14. Dez 2009 14:54

Re: Assembler Files einbinden
 
mmmh,

also ich hab's jetzt mit /omf zusätzlich kompilieren müssen, da MASM standardmäßig coff-files erzeugt (wenn ich mich nicht irre). Und was soll ich sagen; es geht!

Der einzige Unterschied ist, dass du mehrere Code-Segmente (also zwei) gemacht hast. Aber warum ist dass notwendig?

Ich muss wirklich sagen, dass die Verbindung masm / Delphi durchaus komplizierter ist als c / nasm. Da hat man so Probleme nicht. Kannst du evtl. mal 1-2 Sätze dazu sagen, warum dass hier notwendig ist?

gammatester 14. Dez 2009 15:34

Re: Assembler Files einbinden
 
Zitat:

Zitat von FrEEzE2046
mmmh,

also ich hab's jetzt mit /omf zusätzlich kompilieren müssen, da MASM standardmäßig coff-files erzeugt (wenn ich mich nicht irre). Und was soll ich sagen; es geht!

Masm ohne /Optionen versucht offensichtlich ein EXE zu erzeugen und macht dabei eine COFF-Umwandlung: XX.obj : warning LNK4033: converting object format from OMF to COFF, deshalb mein ml /c

Zitat:

Zitat von FrEEzE2046
Der einzige Unterschied ist, dass du mehrere Code-Segmente (also zwei) gemacht hast. Aber warum ist dass notwendig?

Ich muss wirklich sagen, dass die Verbindung masm / Delphi durchaus komplizierter ist als c / nasm. Da hat man so Probleme nicht. Kannst du evtl. mal 1-2 Sätze dazu sagen, warum dass hier notwendig ist?

Nein, weiß nicht warum. Mit TASM gehts ja auch ohne, liegt vielleicht daran daß TASM auch von Borland war. Das mit dem procx_text war 'ne dunkle Erinnerung, MASM-Hilfe schreibt dazu:
Zitat:

Syntax: .CODE [name]

Description:

Starts a code segment (with segment name <name>, if given) and ends the previous segment, if any. Aligns the segment on a 2-byte boundary (.8086, .186, .286) or a 4-byte boundary (.386, .486). The .MODEL directive must precede this directive.

Segment name <name> is an optional parameter that overrides the default segment name. If <name> is not specified, the assembler generates a segment called _TEXT (tiny, small, compact, and flat models) or <modulename>_TEXT (medium, large, and huge models).
Wahrscheinlich schafft's ein (M)ASM-Profi auch viel einfacher.

Gruß Gammatester

FrEEzE2046 14. Dez 2009 16:31

Re: Assembler Files einbinden
 
Zitat:

Zitat von gammatester
Wahrscheinlich schafft's ein (M)ASM-Profi auch viel einfacher.

Danke für deine Antwort. Naja, in NASM schaff ich's halt auch viel einfacher ;-), aber ich bin ja hier zu MASM gezwungen. Ich werde evtl. auch nochmal schauen, ob ich nicht doch 32-Bit OMF-Files erzeugen kann mit NASM - dass habe ich noch nie gebraucht und daher keine Ahnung.

Kann mir jedenfalls nicht vorstellen, dass man für jede Funktion ein neues Code-Segment bedingen muss ... ist eigentlich ziemlich absurd aus meiner Sicht.

FrEEzE2046 21. Dez 2009 14:34

Re: Assembler Files einbinden
 
Ob man's glauben mag oder nicht:
Der Fehler ist jetzt schon wieder aufgetreten.

Delphi sagt als Warnung immer:
'Falsche globale Symboldefinition'

bei beiden Funktionen. Dass führt in meinem Entwicklungsprojekt jetzt zu einer Zugriffsverletzung in der dcc50.dll.
Was ist falsch am Code?

Code:
TITLE Test.asm
 
.686P
.XMM
.MODEL FLAT


PUBLIC FuncA
PUBLIC FuncB


.CODE FuncA_Code
FuncA PROC
FuncA ENDP


.CODE FuncB_Code
FuncBPROC
FuncBENDP

END

gammatester 21. Dez 2009 15:17

Re: Assembler Files einbinden
 
So kann das eigentlich gar nicht assembliert werden. In
Code:
FuncBPROC
FuncBENDP
fehlen Leerzeichen. Selbst wenn die drin sind, müssen auf jeden Fahll rets rein (sonst rennt die CPU ins Nirvana). Bei mir läuft dieser Code (assembliert mit ml /c test.asm) ohne Probleme in Delphi5 und Delhi6:
Code:
TITLE Test.asm

.686P
.XMM
.MODEL FLAT


PUBLIC FuncA
PUBLIC FuncB


.CODE FuncA_Code
FuncA PROC
ret
FuncA ENDP


.CODE FuncB_Code
FuncB PROC
ret
FuncB ENDP

END
Deklariert in Delphi als
Delphi-Quellcode:
procedure funca; external;
procedure funcb; external;
{$l test.obj}

FrEEzE2046 21. Dez 2009 15:20

Re: Assembler Files einbinden
 
Zitat:

Zitat von gammatester
So kann das eigentlich gar nicht assembliert werden. In
Code:
FuncBPROC
FuncBENDP
fehlen Leerzeichen. Selbst wenn die drin sind, müssen auf jeden Fahll rets rein (sonst rennt die CPU ins Nirvana). Bei mir läuft dieser Code (assembliert mit ml /c test.asm) ohne Probleme in Delphi5 und Delhi6:

Ja, schon gut. Das habe ich doch hier nur schnell exemplarisch hingehauen.
Der Compiler hätte sonst schon gemeckert.

Das Problem ist derweil aber gelöst:
Und zwar hatte ich dem Delphi-Linker mitgeteilt, dass er bitte C-Objekt-Dateien erzeugen soll. Offensichtlich ist dieses Feature eher unausgereift.

gammatester 21. Dez 2009 15:30

Re: Assembler Files einbinden
 
Verstehe nicht ganz was Du machen willst: Der Delphi-Linker soll aus dem ASM/Obj-Files dann C-Obj-Files machen?? (Normalerweiser macht ein Linker keine Obj-Files.)

Wie auch immer: wenn's C bzw. Borland C++ sein soll, muß man wohl die besondere Namenskonventionen von C beachten bzw das Reinmangeln von Parametertypen etc. Dabei kann nun wirklich nicht weiterhelfen; weiß nur, daß es das gibt.

FrEEzE2046 21. Dez 2009 15:44

Re: Assembler Files einbinden
 
Zitat:

Zitat von gammatester
Verstehe nicht ganz was Du machen willst: Der Delphi-Linker soll aus dem ASM/Obj-Files dann C-Obj-Files machen?? (Normalerweiser macht ein Linker keine Obj-Files.)

Also:
Der Fehler lag überhaupt nicht bei meinem Assembler-Code bzw. Object-File, sondern an einer ganz anderen Kannte.
Ich hatte als Linker-Ausgabe (in Delphi) C-Objektdateien gewählt.
Aus irgendeinem Grund scheint dieses Feature aber nicht 100% ausgereift zu seien, da es bei meinem Code Probleme bei der Erzeugung dieser C-Objectdateien gab.

Dies wiederum gab die Fehlermeldung aber in keinster Art und Weiße her, weshalb ich den Fehler in meinem ASM-Code vermutete.

FrEEzE2046 11. Jan 2010 10:18

Re: Assembler Files einbinden
 
Delphi treibt mich in den Wahnsinn, daher muss ich diesen Thread noch mal ausgraben.
Habe ein Objekt-File, dass ich mit MASM folgendermaßen kompiliert habe:

ml /c /omf "source.asm"


Das ganze habe ich dann per "{$LINK "Pfad\source.obj"} in Delphi gelinkt und bekomme aber immer die Meldung: "Falsches Dateiformat".
Warum?

gammatester 11. Jan 2010 12:24

Re: Assembler Files einbinden
 
Zitat:

Zitat von FrEEzE2046
Delphi treibt mich in den Wahnsinn, daher muss ich diesen Thread noch mal ausgraben.
Habe ein Objekt-File, dass ich mit MASM folgendermaßen kompiliert habe:

ml /c /omf "source.asm"


Das ganze habe ich dann per "{$LINK "Pfad\source.obj"} in Delphi gelinkt und bekomme aber immer die Meldung: "Falsches Dateiformat".
Warum?

Was ist das für einen MASM-Version? Alle mir bekannten unterstützen keinen "/omf"-Switch.

FrEEzE2046 11. Jan 2010 15:07

Re: Assembler Files einbinden
 
Zitat:

Zitat von gammatester
Was ist das für einen MASM-Version? Alle mir bekannten unterstützen keinen "/omf"-Switch.

9.0.30729.1
/omf, siehe hier

btw. habe ich in der Vergangenheit ja schon erfolgreich mit MASM32 kompilierte OMF-Objektdateien in Delphi eingebunden. Fragt sich nur, was ich damals anders gemacht habe.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:47 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz