Mathias hat geschrieben: ↑Sa 5. Aug 2023, 08:47
Ich habe noch folgendes durchprobiert, da schein nasm zu funktionieren.
Das ld nicht geht, liegen daran, das man noch irgendeine lib mit "-l" einbinden muss.
Code: Alles auswählen
$ fpc project1.lpr -Anasm -a
Free Pascal Compiler version 3.2.2 [2021/07/09] for x86_64
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling project1.lpr
Assembling project1
Linking project1
5 lines compiled, 0.0 sec
tux@tux-B660M-DS3H-DDR4:~/Schreibtisch/dragon_test_2$ rm ./project1
tux@tux-B660M-DS3H-DDR4:~/Schreibtisch/dragon_test_2$ rm ./project1.o
tux@tux-B660M-DS3H-DDR4:~/Schreibtisch/dragon_test_2$ nasm -f elf64 project1.s
tux@tux-B660M-DS3H-DDR4:~/Schreibtisch/dragon_test_2$ ld project1.o
ld: warning: cannot find entry symbol _start; defaulting to 0000000000401000
ld: project1.o: in function `..@c5':
project1.s:(.text+0xe): undefined reference to `fpc_initializeunits'
ld: project1.s:(.text+0x13): undefined reference to `fpc_get_output'
ld: project1.s:(.text+0x2d): undefined reference to `fpc_write_text_shortstr'
ld: project1.s:(.text+0x32): undefined reference to `fpc_iocheck'
ld: project1.s:(.text+0x3a): undefined reference to `fpc_writeln_end'
ld: project1.s:(.text+0x3f): undefined reference to `fpc_iocheck'
ld: project1.s:(.text+0x44): undefined reference to `fpc_do_exit'
ld: project1.o: in function `INITFINAL':
project1.s:(.data+0x10): undefined reference to `INIT$_$SYSTEM'
ld: project1.o: in function `FPC_THREADVARTABLES':
project1.s:(.data+0x24): undefined reference to `THREADVARLIST_$SYSTEM$indirect'
tux@tux-B660M-DS3H-DDR4:~/Schreibtisch/dragon_test_2$
Ein FPC Programm besteht nicht nur aus dem Hauptprojekt, sondern auch aus allen benötigten Units. Und eine Unit, die
immer benötigt wird, ist die
System-Unit. Das heißt du musst auch die
system.o aus deiner FPC Installation mit rein linken (direkt angegeben, ohne
-l). Oder du rufst FPC einfach mit
-sh auf, das wird dir ein Skript erzeugen, dass die nötigen Assemblerbefehle und den Linkerbefehl und einen Verweis auf das ebenfalls erstellte Linkerskript enthält.
Mathias hat geschrieben: ↑Sa 5. Aug 2023, 13:33
Ich habe mal die beiden *.s verglichen, zwischen Konsolenaufruf und Lazarus-IDE.
Die Dateien unterscheiden sich recht stark, so das ich mir ein *diff" erspart habe. Einzig was gleich ist, der Dialekt.
Im Anhand die beiden Dateien.
Das Lazarus Projekt hat noch aktivierte Debuginformationen.
Mathias hat geschrieben: ↑Sa 5. Aug 2023, 13:33
Auf der Konsole habe ich die *.s so generiert:
Das "-a" braucht es da dringen, ansonsten wird keine *.s erzeugt.
Nicht ganz korrekt. Die Assemblerdateien werden immer erstellt (außer mit dem internen Assembler), der Unterschied ist nur, dass sie ohne
-a wieder gelöscht werden.
Mathias hat geschrieben: ↑Sa 5. Aug 2023, 13:33
Gibt es unter Lazarus nicht irgendwo ein Fenster, wo man nachschauen kann, wie Lazarus das FPC-Kommando aufruft ?
In den Projekteinstellungen unten der Button „
Einstellungen anzeigen”.
Mathias hat geschrieben: ↑So 6. Aug 2023, 08:34
Der grösste Unterschied ist mit aufgefallen, wen die Register ausgehen. C befüllt die Parameter mit push und fpc greift direkt auf die Adresse zu.
FPC nutzt auf
x86_64 eine fixierte Stackgröße, GCC nicht. Bei ersterem wird demnach kein
PUSH/
POP genutzt, da dies die Stackgröße ändern würde.
Mathias hat geschrieben: ↑So 6. Aug 2023, 08:34
Und noch ein feiner Unterschied, wen C printf ohne varargs erkennt, macht er ein puts(). Dafür ist in C die Konstante hello doppelt vorhanden, einmal mit LineEnding das andere mal ohne.
Im Gegensatz zu FPC hat der C Compiler Wissen über die
printf-Funktion, da diese Teil der Standard-C-Bibliothek ist. Dadurch kann der Compiler dann auch entsprechend optimieren (im Fall von
printf ohne weitere Parameter eben die Nutzung von
puts, da er weiß, dass der erste Parameter eine Stringkonstante ist, bei der er noch dazu weiß, dass diese mit
#10 endet, welches für
puts entfernt werden muss).