Maison > développement back-end > C++ > Pourquoi l'utilisation du pointeur de base (%rbp) dans l'assemblage en ligne C provoque-t-elle des défauts de segment ?

Pourquoi l'utilisation du pointeur de base (%rbp) dans l'assemblage en ligne C provoque-t-elle des défauts de segment ?

Linda Hamilton
Libérer: 2025-01-01 07:57:14
original
725 Les gens l'ont consulté

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

Problème : Utilisation du registre de pointeur de base (%rbp) dans un assemblage en ligne C

Lors de l'utilisation d'un assemblage en ligne pour accéder au registre de pointeur de base (%rbp) dans un C fonction, une erreur de segmentation inattendue se produit après l'accès au argument.

Explication

Le problème réside dans le fait de marcher sur la "zone rouge" située sous RSP (ou pointeur de soustraction), qui stocke les valeurs dont GCC doit garder la trace. Dans l'exemple de code fourni, une instruction push est utilisée dans l'assembly en ligne, qui décrémente %rsp de 8 et écrase les 32 bits inférieurs de l'argument de la fonction (&x).

Lorsque l'assembly en ligne est terminé, GCC tente d'utiliser la valeur écrasée comme adresse pour un magasin de 4 octets, conduisant au segment défaut.

Solution

Il existe trois solutions principales à ce problème :

  1. Utilisez un opérande de sortie « mémoire » (tel qu'un tableau de travail) pour l'espace de travail et ne le lisez pas.
  2. Sauter la zone rouge en utilisant add $-128, %rsp / sub $-128, %rsp autour du code assembleur.
  3. Compilez avec -mno-red-zone (mais notez qu'il ne s'agit pas d'une option par fonction).

Approche alternative

Au lieu d'utiliser un dépassement de zone rouge, envisagez d'allouer explicitement un espace de travail au sein de l'assembly en ligne à l'aide d'une contrainte "=m", comme le montre le code corrigé suivant exemple :

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;
}
Copier après la connexion

Ici, la contrainte "=m" garantit que l'espace de travail est alloué dans la zone rouge et évite d'écraser l'argument de la fonction.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal