本文通过分析我们的第一个C语言代码hello.c。从一个最基础的C语言代码预处理到最后的进程的终结,中间经历了预处理、编译、汇编、链接,最后生成可执行文件hello。在运行程序时,通过主存、内存等的配合,创建进程,经过I/O管理,最终完成了hello.c的执行。其中,本文通过借助于诸多工具,包括objdump、edb等,对每一步的结果都进行了详细的分析和解释,使得整个过程思路显得连贯流畅,前后相关,融会贯通。在hello.c完整程序的生命周期中,本文深度梳理了计算机系统的脉络。
关键词:计算机系统;预处理;编译;汇编;链接;进程;存储;I/O
第1章 概述
1.1 Hello简介
Hello程序是一个主要功能是打印的程序。
Hello的P2P:
程序员编写的hello.c件通过预处理、编译、汇编以及链接,依次产生了hello.i、hello.s、hello.o,最后得到可以执行的文件hello。由shell执行命令,创建进程,并且加载可执行文件hello,最终hello.c完成了从program到progress的转变过程。
Hello的020:
Shell在执行hello.c的可执行文件时,为其提供上下文,实现了hello的运行,在经历了可能得中断等异常和信号,并对存储器进行访问等过程,最终成功执行了hello可执行文件,并在hello正常退出后,将资源进行释放,父进程会回收hello进程,内核删除相关的数据。最终表现为从无到有再到无的过程(from zero to zero)。
1.2 环境与工具
硬件系统:Intel i5 x64cpu;32G RAM;512G SSD
软件系统:windows 11;ubuntu 20.04
开发工具:Visual Studio 2022 ; vim; gcc; edb;readelf,objdump等
1.3 中间结果
列出你为编写本论文,生成的中间结果文件的名字,文件的作用等。
hello.c |
源代码文件 |
hello.i |
预处理后的代码文件 |
hello.s |
编译后的汇编语言代码文件 |
hello.o |
汇编后的目标文件 |
hello |
链接后的可执行文件 |
hello_a.txt |
hello.o的反汇编文件 |
hello_b.txt |
hello的反汇编文件 |
1.4 本章小结
这一章主要介绍了hello.c程序的P2P和020过程,介绍了相应的环境配置,通过列出中间文件展示了对hello.c的基本研究过程。
第2章 预处理
2.1 预处理的概念与作用
概念:
预处理是将原始的C语言程序在编译之前进行处理,为编译做准备,包括对#include<>,#define,条件编译#ifdef等,生成相应的.i文件。
作用:
预处理器进行代码文本的替换工作:
1)根据字符#,对原始的C程序进行修改,常见的#include<>语句,预处理器将对应.h文件的内容读取并对原程序的进行扩展,插入到当前文件中。
2)根据#define进行相应替换,
3)选择性的调用#if内的代码,
4)并检查基础的宏定义错误,删除注释,
5)将预定义宏插入代码,提高规范性。
最终得到了对应的.i文件。
2.2在Ubuntu下预处理的命令
gcc -E hello.c -o hello.i
2.3 Hello的预处理结果解析
生成了hello.i文件,如图
相比于源代码,hello.i的代码量大幅增加,这是对源代码进行的扩展。其中包含了大量的stdio.h、unistd.h以及stdlib.h中的代码,最终使得hello.i的文件中没有需要初步解释的宏定义。
将系统中的文件和源代码相互关联。
包含了大量的外部函数
众多的结构体和数据类型
最后是程序的源代码内容。
2.4 本章小结
本章通过说明了预处理的概念和作用,生成了hello.i文件,文件中统一了众多的数据结构,诸多的函数以及源代码部分等。虽然仅仅是一个比较简短的hello.c函数,但是调用读取了诸多的内容。
(第2章0.5分)
第3章 编译
3.1 编译的概念与作用
概念:
就是把代码转化为汇编指令的过程,而汇编指令只是和cpu相关的。
作用:
编译的过程是进行词法分析、语法分析、语义分析以及优化后产生相应的汇编代码文件。编译器将预处理后的代码转换为面向CPU的机器指令,转换后的结果以汇编语言的文本形式保存。这一过程实现了从对人可读的文件转变成为了对机器可读的文件,决定了程序的机器级表示。
其中包括:①检查错误②性能优化等其他功能。
3.2 在Ubuntu下编译的命令
gcc -S hello.i -o hello.s,编译结果得到了hello.s
3.3 Hello的编译结果解析
hello.s
此部分是重点,说明编译器是怎么处理C语言的各个数据类型以及各类操作的。应分3.3.1~ 3.3.x等按照类型和操作进行分析,只要hello.s中出现的属于大作业PPT中P4给出的参考C数据与操作,都应解析。
3.3.1汇编的初始部分
file声明了源文件为“hello.c”,
.text表示代码段,
.section.rodata表示只读代码段
.align声明了对指令或者数据的存放地址进行对齐的方式,8字节对齐
.string声明了一个字符串
.global声明了全局变量
.type声明了一个符号的类型
3.3.2数据部分
3.3.2.1字符串:
程序由俩个字符串存放在只读数据段中,其中俩个字符串均是在源代码程序中表现出来。位于.text中。
3.3.2.2参数argc和参数argv
由此可知-20(%rbp)保留的是argc参数,使用edi传入,argv通过rsi传入由-32(%rbp)保存。
3.3.2.3局部变量
存储局部变量i被存储在栈上的-4(%rbp)的位置
3.3.3基础操作部分
3.3.3.1赋值
对变量赋值:
参数赋值: