Bei Verwendung von Inline-Assembly für den Zugriff auf das Basiszeigerregister (%rbp) in einer C Nach dem Zugriff auf die Funktion tritt ein unerwarteter Seg-Fehler auf Argument.
Das Problem liegt darin, auf die „rote Zone“ unter RSP (oder Subtraktionszeiger) zu treten, in der Werte gespeichert sind, die GCC im Auge behalten muss. Im bereitgestellten Beispielcode wird eine Push-Anweisung innerhalb der Inline-Assembly verwendet, die %rsp um 8 dekrementiert und die unteren 32 Bits des Funktionsarguments (&x) überschreibt.
Wenn die Inline-Assembly abgeschlossen ist, GCC versucht, den überfüllten Wert als Adresse für einen 4-Byte-Speicher zu verwenden, was zum Seg führt Fehler.
Es gibt drei Hauptlösungen für dieses Problem:
Anstatt einen roten Zonenüberlauf zu verwenden, sollten Sie erwägen, explizit Arbeitsbereich innerhalb der Inline-Assembly mithilfe einer „=m“-Einschränkung zuzuweisen, wie im folgenden korrigierten Code zu sehen ist Beispiel:
void Bar(int &x) { int tmp; long tmplong; asm ("lea -16 + %[mem1], %%rbp\n\t" "imul , %%rbp, %q[reg1]\n\t" // q modifier: 64bit name. "add %k[reg1], %k[reg1]\n\t" // k modifier: 32bit name "movl , %[mem1]\n\t" // some asm instruction writing to mem : [mem1] "=m" (tmp), [reg1] "=r" (tmplong) : : "%rbp" ); x = 5; }
Hier stellt die „=m“-Einschränkung sicher, dass der Arbeitsbereich innerhalb der roten Zone zugewiesen wird und verhindert, dass das Funktionsargument überschrieben wird.
Das obige ist der detaillierte Inhalt vonWarum führt die Verwendung des Basiszeigers (%rbp) in der C-Inline-Assembly zu Segfaults?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!