Questo dipende interamente dall'ABI per ciascuna piattaforma. Dato che hai menzionato eax
e ebx
vediamo qual è il caso di x86. In fs/binfmt_elf.c
riga #972, all'interno di load_elf_binary()
, il kernel controlla se l'ABI specifica eventuali requisiti per i valori di registro al caricamento del programma:
/*
* 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.
*/
Quindi chiama ELF_PLAT_INIT
, che è una macro definita per ogni architettura in arch/xxx/include/elf.h
. Per x86, fa quanto segue:
#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)
Quindi, quando il tuo binario ELF collegato staticamente viene caricato su Linux x86, puoi contare su tutti i valori di registro uguali a zero. Non significa che dovresti, però. :-)
Collegamento dinamico
Tieni presente che l'esecuzione di un dinamico il binario collegato esegue effettivamente il codice del linker dinamico nel tuo processo prima che l'esecuzione raggiunga il tuo _start
(Punto di ingresso ELF). Questo può e lascia immondizia nei registri, come consentito dall'ABI. Tranne ovviamente per il puntatore allo stack ESP/RSP e atexit
hook EDX/RDX.
Per i sistemi AMD64 o x86-64 (64 bit) su Linux, l'ABI x86-64 definisce il contenuto iniziale dei registri.
Esistono specifiche simili per i386 ABI, ARM ABI ecc.
Vedi le pagine di wikipedia su ELF e ABI
x86-64 Sistema V ABI
3.4.1 "Initial Stack and Register State" (Basile collegato alla versione PDF di questo):
-
%rsp
punta alla pilaIl puntatore dello stack contiene l'indirizzo del byte con l'indirizzo più basso che fa parte dello stack. È garantito che sia allineato a 16 byte all'ingresso del processo
-
%rdx
un puntatore a funzione che l'applicazione dovrebbe registrare con atexit se è diverso da zero.un puntatore a funzione con cui l'applicazione dovrebbe registrarsi
-
%rbp
non è specificato ma l'area utente dovrebbe impostarlo sul frame di base.Il contenuto di questo registro non è specificato al momento dell'inizializzazione del processo, ma il codice utente dovrebbe contrassegnare il frame dello stack più profondo impostando il puntatore del frame su zero.
-
Tutto il resto non definito.
Linux poi lo segue "perché" lo dice LSB.