Cela dépend entièrement de l'ABI pour chaque plate-forme. Puisque vous mentionnez eax
et ebx
Voyons ce qui est le cas pour x86. En fs/binfmt_elf.c
ligne #972, à l'intérieur de load_elf_binary()
, le noyau vérifie si l'ABI spécifie des exigences pour les valeurs de registre au chargement du programme :
/*
* The ABI may specify that certain registers be set up in special
* ways (on i386 %edx is the address of a DT_FINI function, for
* example. In addition, it may also specify (eg, PowerPC64 ELF)
* that the e_entry field is the address of the function descriptor
* for the startup routine, rather than the address of the startup
* routine itself. This macro performs whatever initialization to
* the regs structure is required as well as any relocations to the
* function descriptor entries when executing dynamically links apps.
*/
Il appelle ensuite ELF_PLAT_INIT
, qui est une macro définie pour chaque architecture dans arch/xxx/include/elf.h
. Pour x86, il effectue les opérations suivantes :
#define ELF_PLAT_INIT(_r, load_addr) \
do { \
_r->bx = 0; _r->cx = 0; _r->dx = 0; \
_r->si = 0; _r->di = 0; _r->bp = 0; \
_r->ax = 0; \
} while (0)
Ainsi, lorsque votre binaire ELF lié statiquement est chargé sur Linux x86, vous pouvez compter sur toutes les valeurs de registre égales à zéro. Cela ne signifie pas pour autant que vous devriez le faire. :-)
Lien dynamique
Notez que l'exécution d'un dynamiquement le binaire lié exécute en fait le code de l'éditeur de liens dynamique dans votre processus avant que l'exécution n'atteigne votre _start
(Point d'entrée ELF). Cela peut laisser et laisse des déchets dans les registres, comme le permet l'ABI. Sauf bien sûr pour le pointeur de pile ESP/RSP et atexit
crochet EDX/RDX.
Pour les systèmes AMD64 ou x86-64 (64 bits) sous Linux, l'ABI x86-64 définit le contenu initial des registres.
Il existe des spécifications similaires pour i386 ABI, ARM ABI, etc.
Voir les pages wikipedia sur ELF et ABI
x86-64 System V ABI
3.4.1 "Initial Stack and Register State" (Basile lié à la version PDF de ceci):
-
%rsp
pointe vers la pileLe pointeur de pile contient l'adresse de l'octet avec l'adresse la plus basse qui fait partie de la pile. Il est garanti d'être aligné sur 16 octets à l'entrée du processus
-
%rdx
un pointeur de fonction que l'application doit enregistrer avec atexit s'il est différent de zéro.un pointeur de fonction avec lequel l'application doit s'enregistrer
-
%rbp
n'est pas spécifié mais l'espace utilisateur doit le définir sur le cadre de base.Le contenu de ce registre n'est pas spécifié au moment de l'initialisation du processus, mais le code utilisateur doit marquer le cadre de pile le plus profond en définissant le pointeur de cadre sur zéro.
-
Tout le reste n'est pas défini.
Linux le suit alors "parce que" le LSB le dit.