Heim >Backend-Entwicklung >C++ >Warum wird das RAX-Register bei Tail Calls mit std::function auf den Stack geschoben?
Stack-Ausrichtung in Tailcall-Situationen
Es stellt sich die Frage, warum das RAX-Register im generierten Assembler-Code zuerst auf den Stack geschoben wird der C-Code, der mit einem std::function-Objekt interagiert.
Die Notwendigkeit von Stack Ausrichtung
Das 64-Bit-ABI schreibt vor, dass der Stapel vor jeder Aufrufanweisung auf 16 Bytes ausgerichtet wird. Wenn ein Aufruf erfolgt, wird eine 8-Byte-Rücksprungadresse auf den Stapel verschoben, wodurch diese Ausrichtung unterbrochen wird. Um dies zu beheben, muss der Compiler Maßnahmen ergreifen, um den Stapel vor dem nachfolgenden Aufruf auf ein Vielfaches von 16 neu auszurichten.
Einen verfügbaren Wert für die Ausrichtung übertragen
Anstatt auszuführen „sub rsp, 8“, das Drücken eines „egal“-Werts wie RAX, erweist sich auf CPUs, die mit einem Stack ausgestattet sind, als effizienter Motor. Dies liegt daran, dass eine einfache Push-Anweisung häufig weniger Prozessoraufwand erfordert als eine Sub-RSP-8-Anweisung.
Vergleich mit einem Tailcall ohne std::function Wrapper
Wenn dort Ist kein std::function-Wrapper vorhanden, wie im Beispiel „void g(void (*a)())“, ist der Tailcall unkompliziert: eine einfache Sprunganweisung (jmp) zum Ziel Funktion. Für die Stapelausrichtung sind keine zusätzlichen Schritte erforderlich, da der Tailcall natürlich die richtige Stapelausrichtung beibehält.
Das obige ist der detaillierte Inhalt vonWarum wird das RAX-Register bei Tail Calls mit std::function auf den Stack geschoben?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!