Nun, dwarf2 für jede Funktion baut Tabellen, die das enthalten, was die Angerufene Register gespeichert werden und wo in dem Stapel sie gespeichert werden, und wo die Rahmenzeiger/Rücksendeadresse in der Aufrufliste ist und einige andere Sachen. Wenn Sie zwerg2 verwenden, kann der Compiler diese Informationen verwenden und die Register effektiv wiederherstellen und im Falle einer Ausnahme zu den Aufrufern zurückspringen. Die Backends müssen Informationen im Prolog-erzeugenden Code ihrer Implementierungen bereitstellen, um GCC mitzuteilen, welche Register auf Abruf gespeichert werden und wann der Frame-Zeiger gespeichert wurde und so etwas.
Mit setjmp/longjmp ist nur ein Hack. Da setjmp/longjmp nicht über die Struktur des Funktionsworfens Bescheid weiß, stellt es alle im jump-buffer gespeicherten Register durch setjmp wieder her, auch wenn sie nicht durch die Wurffunktion übersteuert wurden. Ich bin nicht wirklich ein Experte dafür, aber ich denke, es ist offensichtlich, dass dies nicht effizient sein wird. Jedes Mal, wenn Sie einen try-Block starten, muss setjmp aufgerufen werden, um den Puffer mit den gespeicherten Registern einzurichten, während bei Verwendung von dwarf2 der Compiler bereits alle erforderlichen Informationen zur Kompilierungszeit bereitstellt.
Wenn die Backends nicht die erforderlichen Informationen bereitstellen, greift GCC automatisch auf die auf setjmp/longjmp basierende Ausnahmebehandlung zurück.
Hinweis ich bin kein GCC-Experte. Ich habe die Toolchain einfach auf einen einfachen Prozessor meines Professors portiert, inklusive GCC. Ich hoffe ich konnte dir ein bisschen helfen.
Beachten Sie, dass http://www.nongnu.org/libunwind/ vorhanden ist, das über eine effiziente 'setjmp'-Implementierung verfügt, die wiederum auf Zwergtabellen basiert. Also muss 'setjmp' nur den Stackpointer speichern und den Rest dem bereits funktionierenden Zwergabwickler überlassen. –