3 Stimmen

Ist es möglich, GCC davon zu überzeugen, die Fastcall-Aufrufkonvention zu imitieren?

Also ich habe ein Stück der Baugruppe, die eine Funktion mit der Fastcall-Aufruf-Konvention auf Windows aufrufen muss, aber Gcc nicht (afaict) unterstützt es. GCC bietet das regparm-Attribut, aber das erwartet, dass die ersten 3 Parameter in eax, edx und ecx übergeben werden, während fastcall erwartet, dass die ersten beiden Parameter in ecx und edx übergeben werden.

Ich versuche lediglich zu vermeiden, dass ich einige Codepfade dupliziere, daher ist dies nicht wirklich kritisch, aber es wäre toll, wenn es vermeidbar wäre.

1 Stimmen

Beachten Sie, dass es so etwas wie "die" Fastcall-Aufrufkonvention eigentlich nicht gibt. Was Sie beschrieben haben, entspricht dem, was C++ Builder als Fastcall bezeichnet. Visual C++ scheint die ungerade aus in diesem Fall, für was es wert ist.

12voto

ephemient Punkte 189038

Der GCC unterstützt fastcall , über __attribute__((fastcall)) . Es scheint in GCC 3.4 eingeführt worden zu sein.

0 Stimmen

Werden die ersten beiden Argumente von rechts nach links übergeben und in edx y ecx bzw.?

0 Stimmen

@jww GCC-Handbuch sagt "die fastcall Attribut veranlasst den Compiler, das erste Argument (wenn es vom ganzzahligen Typ ist) in das Register ECX und das zweite Argument (wenn es vom ganzzahligen Typ ist) in das Register EDX zu übertragen." Microsofts __fastcall für das erste und zweite Argument in der gleichen ECX-, EDX-Reihenfolge, beginnend von links. Ich bin mir nicht sicher, warum Sie die Argumente von rechts aus betrachten sollten...

0 Stimmen

"Ich bin mir nicht sicher, warum Sie die Argumente von der rechten Seite aus betrachten..." - Ich glaube, das ist die Art und Weise, wie der Angerufene sie weitergibt - von rechts nach links. Nehmen wir an, es gibt vier Argumente, von denen zwei auf dem Stack und zwei in Registern übergeben werden. In diesem Fall wird das "erste" Argument von links nach rechts auf dem Stack übergeben, nicht in einem Register.

5voto

Ich weiß, ich bin etwas spät dran, aber wenn jemand von Ihnen darüber stolpert, denken Sie daran, dass Sie ein Makro definieren können, das dies nachahmt. Zum Beispiel:

#if defined(__GNUC__)
    #define MSFASTCALL __fastcall
    #define GCCFASTCALL 
#elif defined(_MSC_VER)
    #define MSFASTCALL
    #define GCCFASTCALL __attribute__((fastcall))
#endif

int MSFASTCALL magic() GCCFASTCALL;

Das sieht natürlich ziemlich hässlich aus, also könnte man einfach 2 Prototypen definieren (was ich auch tue), um es etwas übersichtlicher zu machen, aber es gibt Leute, die den Weg bevorzugen, der weniger Tipparbeit erfordert. Ich verwende im Allgemeinen keine Aufrufkonventionen, außer in besonderen Fällen. Den Rest überlasse ich dem Compiler zur Optimierung.

Nun gibt es einige Besonderheiten zu beachten. Wenn Sie zum Beispiel auf 64-Bit-Plattformen arbeiten, verwenden alle Funktionen die Fastcall-Konvention, um die Vorteile der zusätzlichen Register zu nutzen, die Geschwindigkeit zu erhöhen und die Kosten für die Umleitung zu reduzieren. Ebenso wird Fastcall von verschiedenen Plattformen unterschiedlich implementiert, da es nicht standardisiert ist. Es gibt noch einige andere, aber das ist alles, was ich aus dem Kopf ziehen kann.

1voto

Wenn Sie die Funktion aus asm aufrufen, haben Sie sicherlich die vollständige Kontrolle darüber, wie Sie die Funktion aufrufen. Was hindert Sie daran, einfach die Register zu laden und eine CALL ?

1 Stimmen

Das Problem ist, dass der Aufrufer in Assembler ist, die Funktion, die ich aufrufe, in C ist -- und es ist der Codegen des Compilers für die Funktion, die ich aufrufe, der problematisch ist :-(

0 Stimmen

Aaaah...ja, ich nahm an, dass es Ihnen um den Anrufer und nicht um den Angerufenen ging.

0 Stimmen

Keine Sorge, ich dachte mir schon, dass das die Verwirrung ist :D

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X