我在编译器初学者,但我在学习程序是如何组织的(二进制),以及它是如何读取并加载到内存中执行非常感兴趣。 什么电子书/图书/教程做你们建议我阅读了快速启动?
Answer 1:
编译器和可执行的二进制文件远程相关。 (实际的可执行由连接器内置ld
,不是编译器)。
在Linux系统中, Linux内核使用写入时复制和按需分页技术,懒洋洋地加载程序页面, ELF可执行文件。 共享库可以被动态加载 ,优选包含位置无关的代码 。
你可能有兴趣在阅读有关编译器构造 ,莱文的书上的接头和装载机 ,在Linux的大会HOWTO ,该程序库HOWTO中, LDD(1) , 调用execve(2) , 介绍(2) , 叉(2) , MMAP( 2) , dlopen的(3) , 小精灵(5) , PROC(5) , 信号(7)手册页。
也尝试了解cat /proc/self/maps
正显示出你(进程的内存映射这样做cat
)。 您也可以玩objdump
。
Answer 2:
ELF文件布局
一个ELF文件有两个观点:
- 程序头示出了在运行时使用的段
- 节头列出一组二进制的切片的
每个ELF文件由一个ELF头,接着文件数据。
该文件中的数据可以包括:
- 程序头表 ,描述的零个或更多个片段
- 节头表 ,描述的零个或更多个区段
- 数据在程序头表或节头表称为由条目
段包含所必需的文件的运行时执行,而部分包含用于链接和重定位的重要数据的信息。 在整个文件中的任何字节可以最多由一个部分拥有,并且可以有其不被任何部分拥有孤儿字节。
加载程序内存
在计算中,加载程序是操作系统中负责加载程序的一部分。
这是在启动程序的过程中不可缺少的一个阶段,因为它把程序调入内存并准备执行。
加载程序包括:
- 读取的可执行文件中的内容,包含程序文本文件,到存储器
- 进行其他必要的准备工作准备可执行运行。
一旦装载完成,操作系统通过将控制传递给加载的程序代码开始该程序。
在* NIX方式
在Unix系统上,加载器是系统调用处理程序
execve()
Unix加载器的任务包括:
- 验证 (许可,存储器要求等)
- 从磁盘到主存储器 复制程序图像
- 复制 堆栈上的命令行参数
- 初始化寄存器 (例如,堆栈指针)
- 跳转到程序入口点(
_start
)
文章来源: program loading/execution