网站首页 > 基础教程 正文
通常,程序以二进制执行文件的形式座落于磁盘上,比方说a.out或是prog.exe。为了在CPU上运行,程序必须先被带入内存,然后放入一个进程的上下文中。接下来我们会描述这一过程中的步骤,从编译程序到放入内存中。如下图所示:
源文件被编译成目标文件,这些目标文件旨在装入任何物理内存中,这种格式称为可重定位目标文件relocatable object file。接下来,链接器linker将这些可重定位的目标文件组合为单个二进制可执行executable文件。在链接阶段,也可能包括其他目标文件或库,例如标准C或数学库(由标志-lm指定)。
加载器loader用于将二进制可执行文件加载到内存中,使得文件可以在CPU上运行。与链接和加载相关的活动是重定位relocation,重定位将最终地址分配给程序部分,并调整程序中的代码和数据以匹配这些地址,以便例如代码在执行时可以调用库函数并访问其变量。在上图中,我们看到要运行加载程序,所需要做的就是在命令行中输入可执行文件的名称。在UNIX系统上的命令行上输入程序名称(例如./main)时,shell首先使用fork()系统调用创建一个新进程来运行该程序。然后,shell通过exec()系统调用来调用加载程序,并向exec()传递可执行文件的名称。然后,加载程序将指定的程序加载到内存中使用新创建的进程的地址空间。 (使用GUI界面时,双击与可执行文件关联的图标会使用类似的机制调用加载程序。)
到目前为止描述的过程都是假定所有库都链接到可执行文件中并加载到内存中。实际上,大多数系统允许程序在加载程序时动态链接库。例如,Windows支持动态链接库(DLL)。这样做的好处这样做的方法是避免链接和加载可能最终没有被使用到可执行文件中的库。相反,该库是有条件链接的,并且在程序运行时需要时将其加载。例如,在上图中,数学库未链接到可执行文件main中。而是链接器插入重定位信息,使该信息可以在程序加载时动态链接和加载。
目标文件和可执行文件通常具有标准格式,其中包括编译后的机器代码和符号表,其中包含有关程序中引用的函数和变量的元数据。对于UNIX和Linux系统,此标准格式称为ELF(对于可执行和可链接格式Executable and Linkable Format)。可重定位文件和可执行文件有单独的ELF格式。可执行文件的ELF文件中的一条信息是程序的入口点,其中包含程序运行时要执行的第一条指令的地址。 Windows系统使用可移植可执行(Portable Executable,PE)格式,而Mac OS使用Mach-O格式。
ELF 格式
Linux提供了各种不同的指令去识别和评估ELF文件。比如说,file命令识别文件的类型。如果main.o是一个目标文件,且main是一个可执行文件,那么命令:
file main.o
会输出main.o是一个ELF可重定位文件,而命令:
file main
会输出main是一个ELF可执行文件。ELF文件被分成好几个段,通过readlf命令对其评估。
猜你喜欢
- 2024-10-10 Linux系统常用命令大全 linux系统常用命令大全详解
- 2024-10-10 Redis数据类型与常用指令示例 redis数据类型和用法
- 2024-10-10 深入理解Redis原理与应用,总结10个必定掌握要点,5分钟彻底看懂
- 2024-10-10 sqlserver数据库中的高级知识点有哪些?
- 2024-10-10 程序员的福音 - Apache Commons Exec
- 2024-10-10 Linux常用命令分类详解|文件搜索 linux命令分类总结
- 2024-10-10 linux性能工具perf工作原理简析 linux perl
- 2024-10-10 Python-调用系统命令或脚本,快速完成任务
- 2024-10-10 「Docker」命令使用大全,全集一览
- 2024-10-10 DOS常用命令集合 dos所有命令的命令格式
- 最近发表
- 标签列表
-
- gitpush (61)
- pythonif (68)
- location.href (57)
- tail-f (57)
- pythonifelse (59)
- deletesql (62)
- c++模板 (62)
- css3动画 (57)
- c#event (59)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- exec命令 (59)
- canvasfilltext (58)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- node教程 (59)
- console.table (62)
- c++time_t (58)
- phpcookie (58)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)