Éviter la surcharge d'appel de fonction avec le registre de pointeur de base dans l'assemblage en ligne C
Pour utiliser le registre de pointeur de base (%rbp) dans l'assemblage en ligne C , suivez ce code corrigé extrait :
void Foo(int &x) {
int tmp;
long tmplong;
asm volatile(
"lea -16 + %[mem1], %%rbp\n\t"
"imul , %%rbp, %q[reg1]\n\t" // Register allocated to tmplong
"add %k[reg1], %k[reg1]\n\t" // Register allocated to tmp
"movl , %[mem1]\n\t" // Store value in memory pointed to by tmp
: [mem1] "=&m"(tmp), [reg1] "=r"(tmplong)
:
: "%rbp"
);
x = 5;
}
Copier après la connexion
Explication :
- Au lieu de modifier la zone rouge en dessous de %RSP, nous utilisons une variable locale tmp comme tampon pour l'ASM en ligne .
- La mémoire scratch est fournie dans la zone rouge, accessible via %[mem1], et les références %rbp (registre de pointeur de base) pour calculer l'adresse correcte.
- La contrainte "=m" (opérande mémoire) garantit que le compilateur enregistre tmp dans la mémoire pointée par %[mem1].
- Les registres sont alloués par le compilateur pour %[reg1].
- La liste de clobber ": %rbp" informe le compilateur que %rbp est modifié à l'intérieur de l'assemblage en ligne, permettant sa restauration.
Remarques supplémentaires :
- Gardez l'assemblage en ligne simple, principalement pour les instructions que le le compilateur ne peut pas émettre. Utilisez des contraintes au lieu d'instructions de déplacement explicites.
- Préférez écrire des fonctions entières dans l'assembly plutôt que d'utiliser l'assembly en ligne pour les prologues et les épilogues de fonctions.
- Envisagez d'utiliser d'autres ressources d'assembly en ligne telles que le wiki de balise d'assemblage en ligne et le manuel GNU C.
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!