Exemples exécutables minimaux Linux avec analyse de désassemblage
Puisqu'il s'agit d'un détail d'implémentation non spécifié par les normes, jetons simplement un coup d'œil à ce que le compilateur fait sur une implémentation particulière.
Dans cette réponse, je vais soit créer un lien vers des réponses spécifiques qui font l'analyse, soit fournir l'analyse directement ici, et résumer tous les résultats ici.
Tous ces éléments sont dans différentes versions d'Ubuntu / GCC, et les résultats sont probablement assez stables d'une version à l'autre, mais si nous trouvons des variantes, spécifions des versions plus précises.
Variable locale à l'intérieur d'une fonction
Que ce main
soit ou toute autre fonction:
void f(void) {
int my_local_var;
}
Comme indiqué à: Que signifie <value optimized out> dans gdb?
-O0
: pile
-O3
: enregistre s'ils ne débordent pas, empilez autrement
Pour savoir pourquoi la pile existe, voir: Quelle est la fonction des instructions push / pop utilisées sur les registres dans l'assemblage x86?
Variables globales et static
variables de fonction
/* BSS */
int my_global_implicit;
int my_global_implicit_explicit_0 = 0;
/* DATA */
int my_global_implicit_explicit_1 = 1;
void f(void) {
/* BSS */
static int my_static_local_var_implicit;
static int my_static_local_var_explicit_0 = 0;
/* DATA */
static int my_static_local_var_explicit_1 = 1;
}
char *
et char c[]
Comme indiqué à: Où les variables statiques sont-elles stockées en C et C ++?
void f(void) {
/* RODATA / TEXT */
char *a = "abc";
/* Stack. */
char b[] = "abc";
char c[] = {'a', 'b', 'c', '\0'};
}
TODO est-ce que de très gros littéraux de chaîne seront également mis sur la pile? Ou .data
? Ou la compilation échoue-t-elle?
Arguments de fonction
void f(int i, int j);
Doit passer par la convention d'appel appropriée, par exemple: https://en.wikipedia.org/wiki/X86_calling_conventions pour X86, qui spécifie soit des registres spécifiques, soit des emplacements de pile pour chaque variable.
Ensuite, comme indiqué à Que signifie <valeur optimisée sortie> dans gdb? , -O0
puis insère tout dans la pile, tout en -O3
essayant d'utiliser les registres autant que possible.
Cependant, si la fonction est intégrée, ils sont traités comme des locaux ordinaires.
const
Je pense que cela ne fait aucune différence car vous pouvez le typer.
Inversement, si le compilateur est capable de déterminer que certaines données ne sont jamais écrites, il pourrait en théorie les placer .rodata
même si ce n'est pas const.
Analyse TODO.
Pointeurs
Ce sont des variables (qui contiennent des adresses, qui sont des nombres), donc comme tout le reste :-)
malloc
La question n'a pas beaucoup de sens pour malloc
, puisque malloc
c'est une fonction, et dans:
int *i = malloc(sizeof(int));
*i
est une variable qui contient une adresse, elle relève donc du cas ci-dessus.
Quant au fonctionnement de malloc en interne, lorsque vous l'appelez le noyau Linux marque certaines adresses comme inscriptibles sur ses structures de données internes, et lorsqu'elles sont touchées par le programme initialement, une erreur se produit et le noyau active les tables de pages, ce qui permet l'accès sans segfaul: comment fonctionne la pagination x86?
Notez cependant que c'est fondamentalement exactement ce que fait l' exec
appel système sous le capot lorsque vous essayez d'exécuter un exécutable: il marque les pages sur lesquelles il veut charger et y écrit le programme, voir aussi: Comment le noyau obtient-il un fichier binaire exécutable fonctionnant sous Linux? Sauf que cela exec
a des limitations supplémentaires sur l'endroit où charger (par exemple, le code n'est-il pas déplaçable ).
L'appel système exact utilisé malloc
est mmap
dans les implémentations modernes de 2020, et dans le passé brk
était utilisé: malloc () utilise-t-il brk () ou mmap ()?
Bibliothèques dynamiques
Fondamentalement, mmap
accédez à la mémoire: /unix/226524/what-system-call-is-used-to-load-libraries-in-linux/462710#462710
variables d'environnement et main
deargv
Au-dessus de la pile initiale: /unix/75939/where-is-the-environment-string-actual-stored TODO pourquoi pas en .data?