Dies hängt ganz von der ABI für jede Plattform ab. Da Sie eax
erwähnen und ebx
Mal sehen, was für x86 der Fall ist. In fs/binfmt_elf.c
Zeile #972, innerhalb von load_elf_binary()
, prüft der Kernel, ob die ABI irgendwelche Anforderungen für Registerwerte beim Programmladen spezifiziert:
/*
* 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.
*/
Es ruft dann ELF_PLAT_INIT
auf , ein Makro, das für jede Architektur in arch/xxx/include/elf.h
definiert ist . Für x86 macht es Folgendes:
#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)
Wenn also Ihre statisch verknüpfte ELF-Binärdatei unter Linux x86 geladen wird, können Sie sich darauf verlassen, dass alle Registerwerte gleich Null sind. Das heißt aber nicht, dass Sie das tun sollten. :-)
Dynamische Verknüpfung
Beachten Sie, dass dynamisch ausgeführt wird verknüpfte Binärdatei führt tatsächlich dynamischen Linker-Code in Ihrem Prozess aus, bevor die Ausführung Ihren _start
erreicht (ELF-Einstiegspunkt). Dies kann und wird Müll in den Registern hinterlassen, wie von der ABI erlaubt. Außer natürlich für den Stapelzeiger ESP/RSP und atexit
Hook EDX/RDX.
Für AMD64- oder x86-64-Systeme (64 Bit) unter Linux definiert die x86-64-ABI den anfänglichen Inhalt von Registern.
Ähnliche Spezifikationen gibt es für i386 ABI, ARM ABI etc.
Siehe Wikipedia-Seiten zu ELF und ABI
x86-64 System V ABI
3.4.1 "Initial Stack and Register State" (Basile verlinkt auf die PDF-Version davon):
-
%rsp
zeigt auf den StackDer Stapelzeiger enthält die Adresse des Bytes mit der niedrigsten Adresse, das Teil des Stapels ist. Es ist garantiert, dass es beim Prozesseintritt 16-Byte-ausgerichtet ist
-
%rdx
ein Funktionszeiger, den die Anwendung bei atexit registrieren soll, wenn er nicht Null ist.ein Funktionszeiger, bei dem sich die Anwendung registrieren soll
-
%rbp
ist nicht spezifiziert, aber das Userland sollte es auf den Basis-Frame setzen.Der Inhalt dieses Registers ist zum Zeitpunkt der Prozessinitialisierung nicht spezifiziert, aber der Benutzercode sollte den tiefsten Stapelrahmen markieren, indem er den Rahmenzeiger auf Null setzt.
-
Alles andere undefiniert.
Linux folgt ihm dann, "weil" das LSB es so sagt.