计算机系统大作业--程序人生-Hello’s P2P

摘  要

本文通过分析hello程序从C文件如何转变为可执行文件的全过程,包括预处理、编译、汇编、链接阶段,每一步如何对上一步形成的文件进行操作,形成新文件的过程。hello进程在shell执行的过程,存储管理的过程,I/O处理的过程。以这些过程的分析为例,阐明整个程序的生命周期。

关键词:预处理;编译;汇编;连接;存储管理   

目  录

 

第1章 概述 - 4 -

1.1 Hello简介 - 4 -

1.2 环境与工具 - 4 -

1.3 中间结果 - 4 -

1.4 本章小结 - 4 -

第2章 预处理 - 5 -

2.1 预处理的概念与作用 - 5 -

2.2在Ubuntu下预处理的命令 - 5 -

2.3 Hello的预处理结果解析 - 5 -

2.4 本章小结 - 5 -

第3章 编译 - 6 -

3.1 编译的概念与作用 - 6 -

3.2 在Ubuntu下编译的命令 - 6 -

3.3 Hello的编译结果解析 - 6 -

3.4 本章小结 - 6 -

第4章 汇编 - 7 -

4.1 汇编的概念与作用 - 7 -

4.2 在Ubuntu下汇编的命令 - 7 -

4.3 可重定位目标elf格式 - 7 -

4.4 Hello.o的结果解析 - 7 -

4.5 本章小结 - 7 -

第5章 链接 - 8 -

5.1 链接的概念与作用 - 8 -

5.2 在Ubuntu下链接的命令 - 8 -

5.3 可执行目标文件hello的格式 - 8 -

5.4 hello的虚拟地址空间 - 8 -

5.5 链接的重定位过程分析 - 8 -

5.6 hello的执行流程 - 8 -

5.7 Hello的动态链接分析 - 8 -

5.8 本章小结 - 9 -

第6章 hello进程管理 - 10 -

6.1 进程的概念与作用 - 10 -

6.2 简述壳Shell-bash的作用与处理流程 - 10 -

6.3 Hello的fork进程创建过程 - 10 -

6.4 Hello的execve过程 - 10 -

6.5 Hello的进程执行 - 10 -

6.6 hello的异常与信号处理 - 10 -

6.7本章小结 - 10 -

第7章 hello的存储管理 - 11 -

7.1 hello的存储器地址空间 - 11 -

7.2 Intel逻辑地址到线性地址的变换-段式管理 - 11 -

7.3 Hello的线性地址到物理地址的变换-页式管理 - 11 -

7.4 TLB与四级页表支持下的VA到PA的变换 - 11 -

7.5 三级Cache支持下的物理内存访问 - 11 -

7.6 hello进程fork时的内存映射 - 11 -

7.7 hello进程execve时的内存映射 - 11 -

7.8 缺页故障与缺页中断处理 - 11 -

7.9动态存储分配管理 - 11 -

7.10本章小结 - 12 -

第8章 hello的IO管理 - 13 -

8.1 Linux的IO设备管理方法 - 13 -

8.2 简述Unix IO接口及其函数 - 13 -

8.3 printf的实现分析 - 13 -

8.4 getchar的实现分析 - 13 -

8.5本章小结 - 13 -

结论 - 14 -

附件 - 15 -

参考文献 - 16 -

 

 

第1章 概述

1.1 Hello简介

1.什么是Hello程序:

hello程序由用户通过键盘输入,根据高级语言的语法规范形成编译器能够读懂的代码。

  1. Hello程序是怎么形成的:

完成后的hello.c文件依次经过编译器的预处理对源代码进行转换、编译得到汇编语言代码、汇编再将汇编语言转换为机器语言,最后与库函数进行链接并进行重定位,形成可执行文件。

  1. Hello的可执行文件:

hello的可执行文件可以通过shell运行并传入命令行参数。shell同样是一个程序,它会通过fork函数为hello创建一个进程,再通过execve执行hello。操作系统的并发机制让hello程序能够与其他程序分片运行。

  1. 作为一个进程,hello是由操作系统将其的各类信息包括代码、数据等从磁盘加载到内存得以有效的执行。CPU读取其代码并以流水线的方式执行,通过高速缓存高效的读取指令,将程序的各个指令在硬件上实现。
  2. 当hello对数据进行处理时,其空间在内存上申请。操作系统提供的虚拟内存机制为每个进程维护了自己的空间,从而不会相互干扰。计算机存储结构层层递进,下一级作为上一级的缓存,让hello的数据能够从磁盘传输到CPU寄存器。
  3. TLB、分级页表等机制又为数据在内存中的高效访问提供了支持,合理的信号机制又让hello程序能够应对执行中的各种情况。操作系统将I/O设备都抽象为了文件,将底层与应用层隔离,将用户态与内核态隔离,通过描述符与接口,让hello程序能够间接调用硬件进行输入输出,例如从键盘读入字符,向屏幕输出内容。hello程序终止后,父进程shell与操作系统一同将其回收,释放其运行过程中占用的内存空间。
  4. P2P过程:即From program to process,从程序到进程。hello程序编写后,通过预处理、编译、汇编和链接等四个步骤形成一个可执行文件。其中,预处理是指预处理器(Preprocessor)处理以#开始的预编译指令,如宏定义(#define)、头文件引用(#include)、条件编译(#ifdef)等;编译是指使用编译器(Compiler)将C语言,翻译汇编代码;汇编是指使用汇编器(Assembler)将汇编代码翻译成二进制机器语言;而链接是指使用链接器(Linker)将汇编器生成的目标文件外加库链接为一个可执行文件。
  5. 020过程:

shell首先fork一个子进程,然后通过execve加载并执行hello,映射虚拟内存,进入程序入口后将程序载入物理内存,进入main函数执行目标代码,CPU为运行的hello分配时间片执行逻辑控制流。当程序运行结束后,shell父进程负责回收hello进程,内核删除相关数据结构。即,从0开始,以0结束,为020。

1.2 环境与工具

1.硬件环境:Intel Core i5 X64 CPU;2.5GHz;8G RAM;128G SSD + 1T HDD;

2.软件环境:Windows 10 64位; VMware 14;Ubuntu 16.04 LTS 64位;

 

3.开发与调试工具:GDB;EDB;OBJDUMP;READELF;CodeBlocks 64位;vim/gedit+gcc;

1.3 中间结果

1.hello.c:hello源文件;

2.hello.i:hello.c预编译的结果,用于研究预编译的作用以及进行编译器的下一步编译操作;

3.hello.s:hello.i编译后的结果,用于研究汇编语言以及编译器的汇编操作,可以与hello.c对应,分析底层的实现;

4.hello.o:hello.s汇编后的结果,可重定位目标程序,没有经过链接,用于链接器或编译器链接生成最终可执行程序;

5.hello.out:hello.o链接后生成的可执行目标文件,可以用来反汇编或者通过EDB、GDB等工具分析链接过程以及程序运行过程,包括进入main函数前后发生的过程;

6.hello:同hello.out,由gcc -m64 -no-pie -fno-PIC hello.c -o
hello命令直接生成;

1.4 本章小结

本章简要介绍了hello程序从代码到编译生成,到执行,再到终止的过程与操作系统发生的事件,分析了其P2P和020的过程,列出了本次任务的硬件、软件环境和调试工具,并且列举了任务过程中出现的中间产物及其作用。

第2章 预处理

2.1 预处理的概念与作用

1.预处理的概念:

  (1)预处理是指预处理器(cpp)根据以字符#开头的命令,修改原始的C程序,比如#include <stdio.h>命令告诉预处理器读取系统头文件stdio.h的内容,并把它直接插入程序文本中。其他常见的预处理指令还有#define(定义宏)、#if、#ifdef、#endif等。

(2)预处理的结果就得到了另外一个C程序,通常是以.i作为文件扩展名。

2.预处理的作用:

  预处理的过程中,对于引用一些封装的库或者代码的这些命令来说,预处理器会读取头文件中用到的库的代码,将这段代码直接插入到程序文件中;对于宏定义来说,会完成对宏定义的替换;注释会直接删除掉。最后将处理过后的新的文本保存在hello.i中。预处理阶段的作用是让编译器在随后对文本进行编译的过程中,更加方便,因为访问库函数这类操作在预处理阶段已经完成,减少了编译器的工作。

 

2.2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值