程序启动时默认的寄存器状态是什么(asm,linux)?
- 2024-11-08 09:04:00
- admin 原创
- 32
问题描述:
当程序启动时(Linux ELF 可执行文件),、等中是否有零eax
,ebx
或者可以有任何东西?
(我没有进行任何调用或者使用外部库)。
在我的计算机上,寄存器被清零,但是在编写 asm 程序时我可以依赖新进程中的这种行为吗?
解决方案 1:
这完全取决于每个平台的 ABI。既然您提到了eax
,ebx
让我们看看 x86 的情况(截至 Linux v5.17.5)。在 中fs/binfmt_elf.c
,load_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) \n do { \n _r->bx = 0; _r->cx = 0; _r->dx = 0; \n _r->si = 0; _r->di = 0; _r->bp = 0; \n _r->ax = 0; \n } while (0)
因此,当您的静态链接 ELF 二进制文件加载到 Linux x86 上时,您可以指望所有寄存器值都等于零。但这并不意味着您应该这样做。:-)
动态链接
请注意,执行动态_start
链接的二进制文件实际上会在执行到达(ELF 入口点) 之前在进程中运行动态链接器代码。这确实会在寄存器中留下垃圾,这是 ABI 允许的。 当然,堆栈指针 ESP/RSP 和钩子 EDX/RDX 除外atexit
。
解决方案 2:
对于 Linux 上的 AMD64 或 x86-64 系统(64 位),x86-64 ABI定义了寄存器的初始内容。
i386 ABI、ARM ABI等也有类似的规范。
请参阅维基百科上有关ELF和ABI的页面
解决方案 3:
x86-64 System V ABI
3.4.1 “初始堆栈和寄存器状态”(Basile 链接到此内容的 PDF 版本):
%rsp
指向堆栈
堆栈指针保存的是堆栈中地址最低的字节的地址。保证在进程入口处是 16 字节对齐的
%rdx
如果函数指针非零,则应用程序应该向 atexit 注册该函数指针。
应用程序应该注册的函数指针
%rbp
未指定,但用户空间应该将其设置为基准框架。
该寄存器的内容在进程初始化时未指定,但用户代码应通过将帧指针设置为零来标记最深的堆栈帧。
其余一切未定义。
然后 Linux 遵循它“因为” LSB这么说。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件