Hallo,
Zeitkritische Funktionen schreibe ich gern in Assembler.
Mein Problem ist, das Lazarus abhängig vom Datentyp immer andere Register verwendet.
Damit meine ich weder Unterschiede für unterschiedliche Hardware noch den Unterschied bei Objekten!
Beispiel:
procedure xyz (var PC1 : PAnsichar ....... assembler;
PC1 kommt in RDI an und kann benutzt werden
MOV RAX, RDI - Result in RAX wird vom Programm so übernommen wie erwartet
aber:
procedure xyz (var P : Pointer ....... assembler;
es kommt weder P in irgend einem Register an, noch kann ich den Rückgabewert von P so in ein Register schreiben, das das Programm es verwenden kann !
Ich behelfe mich zur Zeit damit, das ich jedes Mal erst im Schrittbetrieb im Registerfenster überprüfe ob die Daten wo wirklich dort angekommen sind, wo ich sie erwarte.
Das ist einfach nur lästig.
Kennt jemand eine Dokumentation, wo die Übergabe eindeutig beschrieben ist ? Ich habe bisher nichts gefunden.
Parameterübergabe in Assemblerfunktionen
-
- Lazarusforum e. V.
- Beiträge: 3178
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: Parameterübergabe in Assemblerfunktionen
Mehr als Programmer's Guide: 6.3 Calling mechanism ist mir nicht bekannt.aro hat geschrieben: Fr 14. Mai 2021, 15:37 Kennt jemand eine Dokumentation, wo die Übergabe eindeutig beschrieben ist ? Ich habe bisher nichts gefunden.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
-
- Beiträge: 955
- Registriert: Mi 3. Jun 2020, 07:18
- OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
- CPU-Target: Aarch64 bis Z80 ;)
- Wohnort: München
Re: Parameterübergabe in Assemblerfunktionen
Je nach Datentyp ist das auch durchaus so vorgeschrieben (zum Beispiel werden oft record Typen, die kleiner als die Wortbreite sind in einem Register statt als Referenz übergeben). Rein bei Pointern wie du unten schreibst, kommt das jedoch nicht vor.aro hat geschrieben: Fr 14. Mai 2021, 15:37 Mein Problem ist, das Lazarus abhängig vom Datentyp immer andere Register verwendet.
Du solltest deine Assemblerfunktionen mit nostackframe versehen, da sonst der Compiler die übergebenen Parameter auf dem Stack ablegt und dafür eventuell die übergebenen Register mitnutzt. Ohne nostackframe solltest du die Parameter nicht über die Register holen, sondern über die jeweiligen Parameternamen (z.B. mov r12, P oder so).aro hat geschrieben: Fr 14. Mai 2021, 15:37 Beispiel:
procedure xyz (var PC1 : PAnsichar ....... assembler;
PC1 kommt in RDI an und kann benutzt werden
MOV RAX, RDI - Result in RAX wird vom Programm so übernommen wie erwartet
aber:
procedure xyz (var P : Pointer ....... assembler;
es kommt weder P in irgend einem Register an, noch kann ich den Rückgabewert von P so in ein Register schreiben, das das Programm es verwenden kann !
Einfacher ist es, wenn du mit -al kompilierst, dann kannst du dir den kompletten Assemblycode anschauen (es gibt dann im Unitausgabeverzeichnis neben unitname.o und unitname.ppu noch ein unitname.s).aro hat geschrieben: Fr 14. Mai 2021, 15:37 Ich behelfe mich zur Zeit damit, das ich jedes Mal erst im Schrittbetrieb im Registerfenster überprüfe ob die Daten wo wirklich dort angekommen sind, wo ich sie erwarte.
Das ist einfach nur lästig.
Du hast nicht geschrieben welche Platform du verwendest, deshalb:aro hat geschrieben: Fr 14. Mai 2021, 15:37 Kennt jemand eine Dokumentation, wo die Übergabe eindeutig beschrieben ist ? Ich habe bisher nichts gefunden.
Unter x86_64-win64 folgt FPC der entsprechenden Windows Calling Convention. Auf allen anderen x86_64 Platformen folgt FPC der Sys V Convention.
FPC Compiler Entwickler
-
- Beiträge: 130
- Registriert: Di 26. Jul 2011, 19:58
- OS, Lazarus, FPC: Deepin 20.2; Lazarus 2.0.0 + dfsg-2
- CPU-Target: 64Bit
Re: Parameterübergabe in Assemblerfunktionen
Hallo,
Danke für die Info.
Ich verwende nur noch LINUX 64 Bit (Deepin), Lazarus Version #:2.0.0 + dfsg-2
FPC- Version 3.0.4
Sehr interessant erscheint mir
Ich habe dort -al eingetragen.
Wenn ich den Haken bei Linker zusätzliche Einstellungen .... nicht setzte passiert auch nichts
Wenn ich den Haken setze bekomme ich bei Neu Kompilieren die Fehlermeldung "Error while linking"
Was mache ich falsch ? Wo gehört der Eintrag hin ?
Danke für die Info.
Ich verwende nur noch LINUX 64 Bit (Deepin), Lazarus Version #:2.0.0 + dfsg-2
FPC- Version 3.0.4
Sehr interessant erscheint mir
Aber irgend wie will es nicht klappen. Die einzige mir sinnvolle Möglichkeit habe ich bei Projekteinstellungen / Kompilieren und linken / Linken gefundenEinfacher ist es, wenn du mit -al kompilierst, dann kannst du dir den kompletten Assemblycode anschauen (es gibt dann im Unitausgabeverzeichnis neben unitname.o und unitname.ppu noch ein unitname.s).
Ich habe dort -al eingetragen.
Wenn ich den Haken bei Linker zusätzliche Einstellungen .... nicht setzte passiert auch nichts
Wenn ich den Haken setze bekomme ich bei Neu Kompilieren die Fehlermeldung "Error while linking"
Was mache ich falsch ? Wo gehört der Eintrag hin ?
-
- Beiträge: 955
- Registriert: Mi 3. Jun 2020, 07:18
- OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
- CPU-Target: Aarch64 bis Z80 ;)
- Wohnort: München
Re: Parameterübergabe in Assemblerfunktionen
Alle Optionen, für welche die IDE keine eigenen Einstellmöglichkeiten anbietet, gehören unter Compilereinstellungen -> Benutzerdefinierte Einstellungen
FPC Compiler Entwickler