计算机科学与技术学院
2021年5月
摘 要
hello作为程序员特有的入门语言,几乎出现在所有入门程序当中。但看似简单的hello当中蕴含计算机科学的奥秘,在回到hello,我们去看看其中的实现过程,以及更进一步的底层逻辑。从预处理到编译,从编译到汇编,再到链接产生可执行程序,最后由系统调用执行的个中过程,实在是精妙绝伦。
关键词:计算机系统;hello;编译;
(摘要0分,缺失-1分,根据内容精彩称都酌情加分0-1分)
目 录
第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简介
根据Hello的自白,利用计算机系统的术语,简述Hello的P2P,020的整个过程。
P2P是From Program to Process的缩写,Hello.c从一个.c文件,经过预处理,编译,汇编,链接得到可执行二进制文件,再通过系统创建一个新进程并且加载程序内容,就是由程序到进程的过程。
020是From Zero-0 to Zero-0,读取hello文件,通过execve函数创建进程,等到hello执行完毕结束后,成为僵尸进程,等待被回收。
1.2 环境与工具
列出你为编写本论文,折腾Hello的整个过程中,使用的软硬件环境,以及开发与调试工具。
软件环境:windows 10 ;ubuntu-20.04.4 ;VirtualBox 6.1
硬件环境:x64 2.1GHz ; 16.0 GB RAM
开发与调试工具:codeblocks ; gdb ; objdump ; vscode ;readelf
1.3 中间结果
列出你为编写本论文,生成的中间结果文件的名字,文件的作用等。
hello.i 预处理得到的中间结果
hello.s hello.i编译后得到的汇编文本文件
hello.o hello.s汇编后得到的可重定位目标文件
hello.o_elf:hello.o用readelf -a hello.o指令生成的文件。
hello 链接后得到的可执行目标文件
1.4 本章小结
Hello 程序运行概况,P2P 和 020的过程,hello从编写到运行的全过程,计算机的各个层面协同工作。
(第1章0.5分)
第2章 预处理
2.1 预处理的概念与作用
概念:预处理是把源程序变成可执行文件的第一步,预处理包括以下一些步骤,删除并添加define 的宏,添加include的头文件,删除注释,添加行号和文件名标识,处理条件预编译指令。
作用:对源程序进行的基础性处理,剔除不必要的信息,为之后的处理作铺垫。
2.2在Ubuntu下预处理的命令
gcc -E hello.c -o hello.i
2.3 Hello的预处理结果解析
可以看见加入头文件使代码编程3千多行
如前所说,添加了行号,删除了注释
文件名标识
2.4 本章小结
介绍了Ubuntu在预处理时的指令,介绍与处理的概念和作用,比较预处理后的程序和源程序的差异。
(第2章0.5分)
第3章 编译
3.1 编译的概念与作用
概念:将高级程序语言形式的文本文件,经过语法分析、语义分析等,转化为汇编语言形式的过程。
作用:使程序转变得更利于机器理解,为后续汇编作铺垫。
3.2 在Ubuntu下编译的命令
3.3 Hello的编译结果解析
程序已经转化为汇编语言格式,包含一些文件描述信息
3.3.1 局部变量
对i++ 的操作 每次加1,与7比较
3.3.2 字符串常量
可以看见出于.rodata中,是只读的状态
其中hello 前后的数字是汉字八进制表示
把字符串首地址传给寄存器实现字符串引用
3.3.3 赋值语句的操作
使用movl指令直接赋初值
3.3.4 算数运算 i++
通过addl指令实现加1的操作
3.3.5 跳转语句
jmp指令直接跳转或者j*对条件码判断跳转
3.3.6 数组、指针的引用
通过起始地址加偏移量的方式为argv数组赋值
栈中保存着输入参数存入的内存地址
3.3.7 函数操作
从内存中读取数据和直接引用字符串常量 存入寄存器
然后call指令进行函数调用
3.4 本章小结
本章介绍编译的概念和作用,对编译产生的汇编文本文件进行分析,对高级程序语言到汇编语言转化的理解更加清晰。
(第3章2分