程序执行原理揭秘:你的代码是如何“跑”起来的?

一、执行前的准备工作

我们先来看一下程序执行前需要做哪些准备工作。

我们首先需要了解程序的格式。你可以把程序比作一本书,而程序的格式就是这本书的版式,它决定了书的结构和排版。就像我们在阅读书籍时,不同的语言(如英语、中文)会有不同的阅读方式和理解方法一样,不同的操作系统(如Linux、Windows)也会有各自的方式去读取和理解程序。这就是程序格式的作用,它帮助操作系统正确地读取和理解程序。

1.1 程序格式

以Linux为例,我们需要使用ELF(Execuatable and Linkable File Format)格式。在这个格式中,依次主要包括了文件头、代码段、数据段、重定向表和符号表等信息。

文件头就是这本书的封面,它包含了文件的属性,对应的CPU、操作系统等信息。

代码段就像是书中的内容,包含了程序的代码和指令。

数据段就像是书中的图表,包含了程序内设置的初始化数据。

重定向表就像是书中的脚注,链接前整理的不确定的跳转地址。

符号表就像是书中的索引,包含了函数和全局变量的名称与地址对照表。

对于其它操作系统,在Windows中,我们使用的是PE(Portable Executable)格式;在Mac中,我们使用的是Mach-O格式。这些格式都包含了程序或库需要的各种信息,以便于操作系统能正确地加载和执行,但是由于适用于不同的操作系统,它们在文件结构、功能特性以及处理方式上有所差异。例如,ELF支持多种不同的地址空间布局,PE支持延迟加载和数据目录,而Mach-O则支持多架构和动态链接。

我们的程序想要在某种操作系统上运行,就必须以对应的格式组织代码才行。

1.2 Build过程

Build过程就是将程序代码按照某种格式进行组织的过程, 其中包括编译、汇编和链接。。

编译就像是把手稿生成汇编代码或中间代码,生成的是目标文件,这就像是我们的初稿。

汇编就像是把我们的初稿生成机器码,也就是二进制的0和1,但这还不是CPU可以直接执行的指令,这就像是我们的定稿。

链接就像是把我们的定稿打印成书,包括静态链接和动态链接。

静态链接是把程序内部不同子程序的代码段合并,以及其中的共享函数。这个过程是把所有目标文件中的符号表集中起来,根据重定位表,把所有不确定的跳转地址修正为符号表中对应的地址,然后合并目标文件中的各个段,形成可执行文件。就像是把书中的各个章节合并在一起。

动态链接就像是一座图书馆,它可以让多本书(多个程序)共享一些常用的资源,如语言和操作系统基础库,这样就可以节省内存空间。在Windows系统中,这种共享资源的方式使用的是dll文件,而在Linux系统中,使用的是so文件。你可以把这些共享资源看作是放在特定位置的一本书,每个功能就像书中的一个章节,都有自己的位置。当你需要用到某个功能时,就像查阅书中的某个章节一样,你会通过一个目录(程序链接表)找到它在全局目录(全局偏移表)中的位置。全局目录在你需要时会被创建,这样你就能根据目录找到你需要的功能,而不必去翻阅整本书。

二、执行中的过程

当我们的书准备好后,我们就可以开始阅读了。这个过程就像是程序的执行过程。

装载器把可执行文件加载到内存,就像是我们打开书本,准备阅读。

CPU从内存读取指令和数据,就像是我们从书中读取文字和图表。

动态链接的过程就像是我们阅读时需要参考其他书籍。

当程序跳转到要执行共享库代码指令时,就去程序链接表查找地址,程序链接表中定义了指令在全局偏移表中的地址。如果共享库未加载到内存则先加载,然后建立当前程序虚拟内存与共享库内存的映射,并登记执行指令虚拟内存地址到全局偏移表。然后跳转到当前程序为共享库映射的虚拟地址,读取指令并执行。


总的来说,程序的执行就像是我们写书和阅读书的过程。我们首先需要准备好我们的手稿,然后通过编译、汇编和链接,把我们的手稿变成一本可以阅读的书。然后,我们就可以开始阅读这本书,从中获取知识和信息。在这个过程中,我们可能还需要参考其他的书籍,这就是动态链接的过程。

希望通过本文,你能更好地理解程序的执行过程。

相关推荐
望获linux11 小时前
在 ARM 平台上如何实现Linux系统的1秒启动
linux·服务器·开发语言·数据库·操作系统·嵌入式操作系统·arm平台
skaiuijing15 小时前
Sparrow系列拓展篇:对信号量应用问题的深入讨论
c语言·开发语言·算法·中间件·操作系统
vincent_woo1 天前
再学安卓 - init进程
android·操作系统
丶Darling.2 天前
MIT 6.S081 | 操作系统 | Lab1: Xv6 and Unix utilities
linux·服务器·c语言·操作系统·unix·lab·mit 6.s081
skaiuijing2 天前
Sparrow系列拓展篇:消息队列和互斥锁等IPC机制的设计
c语言·开发语言·算法·操作系统·arm
OpenAnolis小助手4 天前
开源生态发展合作倡议
开源·操作系统·龙蜥社区·龙蜥·openanolis
OpenAnolis小助手4 天前
Cloud Kernel SIG 月度动态:发布ANCK 5.10-017.3小版本,引入SMC、TDX等多项特性
操作系统·龙蜥社区·龙蜥sig·anolisos·openanolis
敲上瘾4 天前
操作系统的理解
linux·运维·服务器·c++·大模型·操作系统·aigc
不爱学习的YY酱5 天前
【操作系统不挂科】<CPU调度(13)>选择题(带答案与解析)
java·linux·前端·算法·操作系统
钰爱&5 天前
【操作系统】Linux之网络编程(UDP)(头歌作业)
linux·操作系统