C语言Hello World 第二重

本节将为你揭开程序从文本文件到输出这个过程的神秘面纱。


1. 源码文件到可执行文件

Paste_Image.png

通过预处理、编译、汇编、链接四个步骤,生成了a.out这个默认可执行目标文件,要想在Unix系统上执行该文件,在shell中输入

unix> ./a.out

Shell是一个命令解释器,它是与系统内核交互的窗口。
当前输入命令不是系统内置命令,Shell就会假设这是一个可执行文件,它将加载并运行这个文件。最终的效果就是Shell会打印出“Hello World”。

补充:Linux的目标文件格式有4种,分别是** a.out COFF PE ELF **

2. 硬件体系中加载、执行a.out的过程

下面在系统的整体硬件组成架构中,简单分析下“Hello World”从文本文件到屏幕上输出的过程:

Paste_Image.png
Paste_Image.png
Paste_Image.png
Paste_Image.png

3. 从软件层来剖析a.out的执行流程

当Shell加载并运行a.out的时候,并不是直接操作键盘、显示器、磁盘或者主存,而是依靠操作系统提供的服务。操作系统可以理解为应用程序和硬件之间的一层软件:

Paste_Image.png

操作系统提供两个基本功能:

  • 防止硬件被失控的程序滥用
  • 向应用程序提供简单一致的机制来控制复杂而通常大相径庭的低级硬件设备

操作系统通过几种抽象概念来实现这两个功能--进程虚拟存储器文件

Paste_Image.png

3.1 进程

当a.out被加载到内存执行的时候,操作系统会提供一种假象,好像系统只有这一个程序在执行,并且独占处理器、主存和I/O设备。这个假象是通过进程的概念来实现的。

进程是操作系统对一个正在运行的程序的一种抽象。
进程的地址空间模型如下图:

Paste_Image.png

实际上系统中会有多个进程,它们通过上下文(进程运行所需的所有状态信息)切换交替获取CPU执行时间片,直到执行结束,因为在单处理器系统中,任意时刻只能执行一个进程代码。

以a.out在Shell中执行为例:

Paste_Image.png

此时有两个并发进程 Shella.out,开始只有Shell进程在运行,即等待用户的命令行输入。当输入./a.out命令,并敲击回车,Shell发现不是内置命令,会认为是一个可执行文件。此时会调用fork()拷贝父进程,并在子进程中调用execve()系统调用,删除子进程现有的虚拟存储器段,并创建新的代码、数据、堆和栈段。新的堆和栈初始化为零。通过虚拟地址空间映射到可执行文件页的大小片段。执行a.out这个进程,完毕后,控制权交还给Shell进程。

在此详细阐述一下上面黑体字的过程:

  • fork
    当fork()被当前进程调用,内核为新进程分配一个全局唯一的PID,并对父进程做一个原样拷贝。既然是拷贝父进程,那进程如何拥有独立的进程空间呢?*原因是当fork调用中,虽然是父进程的原样拷贝,但是它将两个进程中的每个页面都标记为只读,并将两个进程中的每个区域结构都标记为私有的写时拷贝,当这两个进程中的任一一个发起写操作时,写时拷贝机制就会创建新的页面,因此,也就为每个进程保持了私有的地址空间抽象概念。 *
    同样的用一幅图来表述写时拷贝机制:
  1. 首先两个进程都映射了私有的写时拷贝对象


    Paste_Image.png
  2. 比如当子进程进行写操作时,写时拷贝机制生效,新的页面创建

Paste_Image.png
  • execve
    上面黑体字部分可以用一幅图来表述:


    Paste_Image.png

    execve()函数在当前进程中加载并运行包含在可执行目标文件a.out中的程序,用a.out程序有效替代了当前程序。加载并运行a.out需要以下几个步骤:

  1. 删除已存在的用户区域。删除当前进程虚拟地址的用户部分中的已存在的区域结构。
  2. 映射私有区域。为新程序的文本、数据、bss和栈区域创建新的区域结构。所有这些新的区域都是私有的、写时拷贝的。文本和数据区域被映射为a.out文件中的文本和数据区。bbs区域是请求二进制零的,映射到匿名文件,其大小包含在a.out中。栈和堆区域也是请求二进制零的,初始长度为零。上图Linux运行时存储器映像 概括了私有区域的不同映射。
  3. 映射共享区域。如果a.out程序与共享对象(或目标)链接,比如标准库C库libc.so,那么这些对象都是动态链接到这个程序的,然后再映射到用户虚拟地址空间中共享区域内。
  4. 设置程序计数器(PC)。execve做的最后一件事就是设置当前进程上下文中的程序计数器,使之指向文本区域的入口点。
    下一次调度到这个进程时,它将从这个入口点开始执行。Linux讲根据需要换入代码和数据页面。

3.2 虚拟存储器

要理解虚拟存储器,需要先明白三个概念:物理地址虚拟地址地址空间

  • 物理地址
    计算机的主存被组织成一个由M个连续的自己大小的单元组成的数组,每个字节都有一个唯一的物理地址。

    Paste_Image.png

    上图所示是直接从地址4开始读取4个字节(比如32位系统中的一条指令)
    上图中的物理地址空间大小是2的M次方。

  • 虚拟地址
    虚拟地址是CPU生成的,这个地址在被传送到存储器之前,会先转换成物理地址。CPU芯片上有一个 存储器管理单元(Memory Management Unit, MMU) 专门负责地址翻译。

    Paste_Image.png

    虚拟地址空间的大小是2的N次方,由系统的的地址总线条数决定,或32,或64位。

那为何要使用虚拟存储器呢?
想像一下,如果每个进程直接使用物理存储器,共享主存会带来存储器管理的各种挑战,比如进程增多需要的存储器就越大,进程之间的相互读写对方的地址空间,引起程序运行的失败等等。

为了更加有效地管理存储器并且少出错,现代系统提供了对主存的抽象概念--虚拟存储器
虚拟存储器是硬件异常、硬件地址翻译、主存、磁盘文件和内核软件的完美交互,它为每个进程提供一个大的、一致的和私有的地址空间。
虚拟存储器提供了3个重要的能力:

  • 它将主存看成是一个存储在磁盘上的地址空间的告诉缓存,在主存中只保存活动区域,并根据需要在磁盘和主存之间来回传送数据,通过这种方式,它高效地使用主存。*
    此处与cache有个相似的特点,就是程序的局部性决定了这种方式的有效性。而且主存与磁盘之间还有个交换区(swap),它用来存放被替换出来的页面。*
  • 它为每个进程提供了一致的地址空间,从而简化了存储器管理。
  • 它保护了灭个进程地址空间不被其它进程破坏。

虚拟存储器虽然对程序员是透明的,也就说程序员不必关心虚拟器的存在,它会默默地为你工作。但是我们也要明白虚拟存储器的细节与原理,因为 虚拟存储器贯穿了程序执行的流程;虚拟存储器提供了强大的功能,比如它能帮助你理解NIO;帮助你理解段错误为何会发生。

虚拟存储器很复杂,具体细节可以参考 操作系统概念深入理解计算机系统 这两本书。

3.3 文件

文件就是存放在磁盘上的实体,比如hello.c就是磁盘上的一个文本文件,a.out就是磁盘上的二进制文件。程序在执行过程中,虚拟存储器机制会根据需要从磁盘上的文件加载所需的数据。
一个进程可以打开多个文件,并且持有它们的文件句柄。

这第二重境界,相信能帮助你揭开一个程序从文本文件到屏幕上输出这个过程的神秘面纱。

参考资料:

  1. 操作系统概念第7版
  1. 深入理解计算机系统
  2. Linux内核剖析0.12
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351

推荐阅读更多精彩内容