Rax, wie ich es verstehe, könnte es aus der ABI etwas aus der Aufruffunktion enthalten. Aber wir sparen es hier und bewegen den Stapel später um 8 Bytes zurück. Der Rax auf dem Stapel ist also, ich denke, nur relevant für das std :: __ throw_bad_function_call () operation ...? < /p>
Der Code:-< /p>
Code: Select all
#include
void f(std::function a)
{
a();
}
< /code>
Ausgabe von gcc.godbolt.org < /code>, mit Clang 3.7.1 -O3: < /p>
f(std::function): # @f(std::function)
push rax
cmp qword ptr [rdi + 16], 0
je .LBB0_1
add rsp, 8
jmp qword ptr [rdi + 24] # TAILCALL
.LBB0_1:
call std::__throw_bad_function_call()
< /code>
Ich bin sicher, der Grund ist offensichtlich, aber ich habe Mühe, es herauszufinden. < /p>
Hier ist ein Tailcall ohne die std :: function < /code> Wrapper zum Vergleich: < /p>
void g(void(*a)())
{
a();
}
< /code>
Die triviale: < /p>
g(void (*)()): # @g(void (*)())
jmp rdi # TAILCALL