Heim > Backend-Entwicklung > C++ > Warum führt die Verwendung des Basiszeigers (%rbp) in der C-Inline-Assembly zu Segfaults?

Warum führt die Verwendung des Basiszeigers (%rbp) in der C-Inline-Assembly zu Segfaults?

Linda Hamilton
Freigeben: 2025-01-01 07:57:14
Original
725 Leute haben es durchsucht

Why Does Using the Base Pointer (%rbp) in C   Inline Assembly Cause Segfaults?

Problem: Verwendung des Basiszeigerregisters (%rbp) in C-Inline-Assembly

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.

Erklärung

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.

Lösung

Es gibt drei Hauptlösungen für dieses Problem:

  1. Verwenden Sie einen „Speicher“-Ausgabeoperanden (z. B. ein Scratch-Array) für den Arbeitsbereich und Lesen Sie nicht daraus.
  2. Überspringen Sie den roten Bereich, indem Sie add $-128, %rsp / sub $-128 verwenden, %rsp um den Assemblercode.
  3. Kompilieren Sie mit -mno-red-zone (beachten Sie jedoch, dass dies keine Option pro Funktion ist).

Alternativer Ansatz

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;
}
Nach dem Login kopieren

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!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage