陈三县+SA18225041+原创作品转载请注明出处 + https://github.com/mengning/linuxkernel/
Table of Contents
一、汇编语言练习
实验要求:使⽤Example的c代码分别⽣成.cpp,.s,.o和 ELF可执⾏⽂件,并加载运⾏,分析.s汇编代码在CPU 上的执⾏过程 。通过实验解释单任务计算机是怎样⼯作的,并 在此基础上讨论分析多任务计算机是怎样⼯作的。
1、GCC的编译过程
一般情况下,C程序的编译过程分为:预处理阶段;编译成汇编代码阶段;汇编代码汇编成目标代码阶段;将目标代码链接成可执行文件阶段。如下图所示:
1.1、预处理阶段
example.c源码如下:
gcc后使用-E参数,输出的文件的后缀为.cpp。即:gcc -E -o example.cpp example.c
打开example.cpp,如下(代码太多无法显示完全):
通过与源代码进行对比,可以发现,所谓的预处理即是在进行编译的第一遍扫描(词法扫描和语法扫描)时,对以符号“#”开头的预处理命令进行翻译,这里面包括三类主要的处理:
*1、在调用宏的地方进行宏替换,即将宏名替换为所定义的相应的字符串;
*2、用实际值替代“define”的文本;
*3、将include包含的标题文件和头文件的具体的内容拷贝到相应的源代码中;
经过上面三个任务过程,最终生成了.cpp预处理文件。预处理之后的.cpp文件,较之前的源文件在字节数上有很大的变化,这就是将stdio.h头文件的具体内容拷贝过来的结果。
1.2、编译成汇编代码阶段
1.2.1、可以使用-S参数说明生成汇编代码后停止工作,由.c源文件直接编译生成.s汇编文件;即 gcc -S -o example.s example.c
1.2.2、 可以使用-x参数说明根据指定的步骤进行工作,然后由cpp-output指明从预处理得到的文件,同时使用-S参数说明生成汇编代码后停止工作;即 gcc -x cpp-output -S -o example1.s example.cpp
wc命令来对比一下两者字节大小上的区别: 其中,第一列表示相应文件中的行数,第二列表示相应文件中的单词数,第三列表示相应文件中的字节数。
打开文件发现两者内容一致:
1.3、编译生成目标代码文件阶段
1.3.1、可以使用-c参数,直接由.c源文件编译生成目标文件;即 gcc -c example.c -o example.o
1.3.2、 可以使用-x参数说明根据指定的步骤进行工作,然后由assembler指明由汇编文件生成相应的文件,同时使用-c参数说明生成目标文件后停止;即 gcc -x assembler -c example.s -o example.o
1.4、 链接生成可执行文件, 链接阶段主要是将各个.o目标文件链接起来,形成具体的可执行文件
1.4.1、使用-o参数,直接由.c源文件编译链接生成可执行文件;
1.4.2 使用-o参数,由.o目标文件链接生成可执行文件
2、分析汇编程序在CPU上的执行过程
执行反汇编命令如下:
得到如下代码: