Parameterübergabe in Assemblerfunktionen

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
aro
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

Parameterübergabe in Assemblerfunktionen

Beitrag von aro »

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.

Socke
Lazarusforum e. V.
Beiträge: 3158
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

Beitrag von Socke »

aro hat geschrieben:
Fr 14. Mai 2021, 15:37
Kennt jemand eine Dokumentation, wo die Übergabe eindeutig beschrieben ist ? Ich habe bisher nichts gefunden.
Mehr als Programmer's Guide: 6.3 Calling mechanism ist mir nicht bekannt.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

PascalDragon
Beiträge: 825
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

Beitrag von PascalDragon »

aro hat geschrieben:
Fr 14. Mai 2021, 15:37
Mein Problem ist, das Lazarus abhängig vom Datentyp immer andere Register verwendet.
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
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 !
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
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.
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
Kennt jemand eine Dokumentation, wo die Übergabe eindeutig beschrieben ist ? Ich habe bisher nichts gefunden.
Du hast nicht geschrieben welche Platform du verwendest, deshalb:

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

aro
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

Beitrag von aro »

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
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).
Aber irgend wie will es nicht klappen. Die einzige mir sinnvolle Möglichkeit habe ich bei Projekteinstellungen / Kompilieren und linken / Linken gefunden
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 ?

PascalDragon
Beiträge: 825
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

Beitrag von PascalDragon »

aro hat geschrieben:
Mo 17. Mai 2021, 10:00
Was mache ich falsch ? Wo gehört der Eintrag hin ?
Alle Optionen, für welche die IDE keine eigenen Einstellmöglichkeiten anbietet, gehören unter Compilereinstellungen -> Benutzerdefinierte Einstellungen
FPC Compiler Entwickler

Antworten