Frage

Ich habe das gesehen fastcall notation vor vielen Funktionen angehängt.Warum wird es verwendet?

War es hilfreich?

Lösung

Diese Notation vor der Funktion wird als "Aufrufkonvention" bezeichnet." Es gibt an, wie (auf einer niedrigen Ebene) der Compiler Eingabeparameter an die Funktion übergibt und ihre Ergebnisse abruft, sobald sie ausgeführt wurde.

Es gibt viele verschiedene Aufrufkonventionen, von denen die beliebteste ist stdcall und cdecl.

Sie denken vielleicht, dass es nur einen Weg gibt, dies zu tun, aber in Wirklichkeit gibt es Dutzende von Möglichkeiten, wie Sie eine Funktion aufrufen und Variablen ein- und ausgeben können.Sie könnten die Eingabeparameter auf einen Stapel legen (Push, Push, Push zum Aufrufen);pop, pop, pop zum Lesen von Eingabeparametern).Oder vielleicht würden Sie sie lieber in Register stecken (das ist fastcall - es versucht, einige der Eingabeparameter in Register für die Geschwindigkeit einzupassen).

Aber was ist dann mit der Bestellung?Schieben Sie sie von links nach rechts oder von rechts nach links?Was ist mit dem Ergebnis - es gibt immer nur eines (vorausgesetzt, es gibt keine Referenzparameter). Platzieren Sie das Ergebnis also auf dem Stapel, in einem Register, an einer bestimmten Speicheradresse?

Nehmen wir auch an, Sie verwenden den Stapel für die Kommunikation - wer hat die Aufgabe, den Stapel nach dem Aufruf der Funktion tatsächlich zu löschen - der Anrufer oder der Angerufene?

Was ist mit dem Sichern und anschließenden Wiederherstellen des Inhalts von (bestimmten) CPU-Registern - sollte der Anrufer dies tun oder garantiert der Angerufene, dass alles so zurückgegeben wird, wie es war?

Die beliebteste Anrufkonvention (bei weitem) ist cdecl, was die Standardaufrufkonvention in C und C ++ ist.Die WIN32-API verwendet stdcall, was bedeutet, dass jeder Code, der die WIN32-API aufruft, verwendet werden muss stdcall für diese Funktionsaufrufe (was es zu einer weiteren beliebten Wahl macht).

fastcall ist ein bisschen seltsam - Leute, die für viele Funktionen mit nur einem In / Out-Parameter realisiert wurden, ist das Pushen und Poppen von einem speicherbasierten Stapel ziemlich viel Aufwand und macht Funktionsaufrufe etwas schwer, so dass die verschiedenen Compiler eingeführt wurden (anders) Aufrufkonventionen, die einen oder mehrere Parameter in Register einfügen, bevor der Rest für eine bessere Leistung in den Stapel gelegt wird.Das Problem ist, dass nicht alle Compiler die gleichen Regeln dafür verwendet haben, was wohin geht und wer was damit macht fastcall, und als Ergebnis müssen Sie vorsichtig sein, wenn Sie es benutzen, weil Sie nie wissen werden, wer was tut.Schließlich sehen Sie Ist Fastcall wirklich schneller? für Informationen über fastcall Leistungsvorteile.

Kompliziertes Zeug.

Etwas Wichtiges zu beachten:fügen Sie keine Anrufkonventionen hinzu oder ändern Sie sie nicht, wenn Sie es nicht wissen genau was Sie tun, denn wenn sowohl der Anrufer als auch der Angerufene der Aufrufkonvention nicht zustimmen, werden Sie wahrscheinlich mit Stapelbeschädigung und einem Segfault enden.Dies geschieht normalerweise, wenn die Funktion in einer DLL / gemeinsam genutzten Bibliothek aufgerufen wird und ein Programm geschrieben wird, das davon abhängt, dass die DLL / SO / dylib eine bestimmte Aufrufkonvention hat (z. B.), cdecl), dann wird die Bibliothek mit einer anderen Aufrufkonvention neu kompiliert (sagen wir, fastcall).Jetzt kann das alte Programm nicht mehr mit der neuen Bibliothek kommunizieren.

Andere Tipps

Wikipedia gibt an, dass

Konventionen mit dem Titel Fastcall wurden nicht standardisiert und wurden je nach Compiler-Anbieter anders umgesetzt.In der Regel führen Fastcall-Anrufkonventionen ein oder mehrere Argumente in Registern, in denen die Anzahl der für den Anruf erforderlichen Speicherzugriffe reduziert wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top