GNU/Linux >> Tutoriels Linux >  >> Linux

Quels registres sont conservés via un appel de fonction Linux x86-64

Voici le tableau complet des registres et leur utilisation à partir de la documentation [Lien PDF] :

r12 , r13 , r14 , r15 , rbx , rsp , rbp sont les registres enregistrés par l'appelé - ils ont un "Oui" dans la colonne "Conservé à travers les appels de fonction".


Approche expérimentale :désassembler le code GCC

Principalement pour le plaisir, mais aussi pour vérifier rapidement que vous avez bien compris l'ABI.

Essayons d'écraser tous les registres avec un assemblage en ligne pour forcer GCC à les sauvegarder et à les restaurer :

main.c

#include <inttypes.h>

uint64_t inc(uint64_t i) {
    __asm__ __volatile__(
        ""
        : "+m" (i)
        :
        : "rax",
          "rbx",
          "rcx",
          "rdx",
          "rsi",
          "rdi",
          "rbp",
          "rsp",
          "r8",
          "r9",
          "r10",
          "r11",
          "r12",
          "r13",
          "r14",
          "r15",
          "ymm0",
          "ymm1",
          "ymm2",
          "ymm3",
          "ymm4",
          "ymm5",
          "ymm6",
          "ymm7",
          "ymm8",
          "ymm9",
          "ymm10",
          "ymm11",
          "ymm12",
          "ymm13",
          "ymm14",
          "ymm15"
    );
    return i + 1;
}

int main(int argc, char **argv) {
    (void)argv;
    return inc(argc);
}

GitHub en amont.

Compiler et désassembler :

 gcc -std=gnu99 -O3 -ggdb3 -Wall -Wextra -pedantic -o main.out main.c
 objdump -d main.out

Le démontage contient :

00000000000011a0 <inc>:
    11a0:       55                      push   %rbp
    11a1:       48 89 e5                mov    %rsp,%rbp
    11a4:       41 57                   push   %r15
    11a6:       41 56                   push   %r14
    11a8:       41 55                   push   %r13
    11aa:       41 54                   push   %r12
    11ac:       53                      push   %rbx
    11ad:       48 83 ec 08             sub    $0x8,%rsp
    11b1:       48 89 7d d0             mov    %rdi,-0x30(%rbp)
    11b5:       48 8b 45 d0             mov    -0x30(%rbp),%rax
    11b9:       48 8d 65 d8             lea    -0x28(%rbp),%rsp
    11bd:       5b                      pop    %rbx
    11be:       41 5c                   pop    %r12
    11c0:       48 83 c0 01             add    $0x1,%rax
    11c4:       41 5d                   pop    %r13
    11c6:       41 5e                   pop    %r14
    11c8:       41 5f                   pop    %r15
    11ca:       5d                      pop    %rbp
    11cb:       c3                      retq   
    11cc:       0f 1f 40 00             nopl   0x0(%rax)

et nous voyons donc clairement que les éléments suivants sont poussés et sautés :

rbx
r12
r13
r14
r15
rbp

Le seul manquant dans la spécification est rsp , mais nous nous attendons à ce que la pile soit restaurée bien sûr. Une lecture attentive du montage confirme qu'il est maintenu dans ce cas :

  • sub $0x8, %rsp  :alloue 8 octets sur la pile pour enregistrer %rdi à %rdi, -0x30(%rbp) , ce qui est fait pour l'assembly en ligne +m contrainte
  • lea -0x28(%rbp), %rsp restaure %rsp avant le sub , c'est-à-dire 5 pops après mov %rsp, %rbp
  • il y a 6 pushs et 6 pops correspondants
  • aucune autre instruction ne touche %rsp

Testé dans Ubuntu 18.10, GCC 8.2.0.


Linux
  1. Linux - Quelles sont les différentes façons de définir les autorisations de fichiers, etc. sur Gnu/linux ?

  2. Quels sont les différents types de shells sous Linux ?

  3. Que sont les pages sales sous Linux

  4. Appeler une fonction de l'espace utilisateur à partir d'un module du noyau Linux

  5. Qu'est-ce que la mémoire haute et la mémoire basse sous Linux ?

Que sont les ports ? Comment vérifier les ports ouverts Linux ?

Comment trouver quelles adresses IP sont connectées à Linux

Que sont les inodes sous Linux ?

Quelles sont les conventions d'appel pour les appels système UNIX et Linux (et les fonctions de l'espace utilisateur) sur i386 et x86-64

Quels registres sont conservés via un appel de fonction Linux x86-64

Quelles applications de montage vidéo sont disponibles sous Linux ?