当程序启动时(linux,elf)- , 等是否有零eax
,ebx
或者可以有任何东西(我没有做任何调用或使用外部库)?在我的机器上确实如此,我可以在编写 asm 程序时中继这种行为吗?
3 回答
这完全取决于每个平台的 ABI。既然你提到了eax
,ebx
让我们看看 x86 是什么情况。在fs/binfmt_elf.c
第 #972 行的 insideload_elf_binary()
中,内核检查 ABI 是否在程序加载时指定了对寄存器值的任何要求:
/*
* 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.
*/
然后它调用ELF_PLAT_INIT
,这是为每个架构定义的宏arch/xxx/include/elf.h
。对于 x86,它执行以下操作:
#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)
因此,当您在 Linux x86 上加载静态链接的 ELF 二进制文件时,您可以指望所有寄存器值都等于 0。但这并不意味着你应该这样做。:-)
动态链接
请注意,在执行到达您的(ELF 入口点) 之前,执行动态链接的二进制文件实际上会在您的进程中运行动态链接器代码。正如 ABI 所允许的那样,这可以而且确实会在寄存器中留下垃圾。 当然堆栈指针 ESP/RSP 和挂钩 EDX/RDX 除外。_start
atexit
对于 Linux 上的 AMD64 或 x86-64 系统(64 位),x86-64 ABI定义了寄存器的初始内容。
x86-64 系统 V ABI
3.4.1“初始堆栈和寄存器状态”(Basile链接到这个的PDF版本):
%rsp
指向堆栈堆栈指针保存作为堆栈一部分的具有最低地址的字节的地址。保证在进程入口处是 16 字节对齐的
%rdx
一个函数指针,如果它不为零,应用程序应该向 atexit 注册。应用程序应注册的函数指针
%rbp
未指定,但用户区应将其设置为基本框架。该寄存器的内容在进程初始化时未指定,但用户代码应通过将帧指针设置为零来标记最深的堆栈帧。
其他一切未定义。
Linux 然后跟随它“因为” LSB这么说。