实验报告

题目:计算机系统第一次试验

班级: 2017211302

学号: 2015211179

姓名: 程生红


2019 年10 月 20 日

一、 实验目的

1、熟悉linux操作的基本操作;

2、掌握gcc编译方法;

3、掌握gdb的调试工具使用;

4、掌握objdump反汇编工具使用;

5、熟悉理解反汇编程序(对照源程序与objdump生成的汇编程序)。

二、实验环境(10分)

Linux版本的Ubuntu

操作系统的三个部分

内核:操作系统五大管理功能一般都由操作系统内核负责。 

外壳:外壳程序负责接收用户操作,提供与用户的交互界面。 

一般操作系统提供给用户的界面主要有两种:文本界面; GUI 图 形界面。

管理工具和附属软件:一般是操作系统在发布时附带提供给用户的,用 户安装完操 作系统,就可以利用操作系统自带的管理工具和软件进行一 些基本的操作。

Vi编辑器

1、Vi编辑器的简介

2、 Vi是Visual interface的简称,它可以执行输出、删除、查找、 替换、块操作等众多文本操作  用户可以根据自己的需要对Vi进行定制,这是其他编辑程序 所没有的。  Vi不是一个排版程序,它不像WORD或WPS那样可以对字体、 格式、段落等其他属性进行编排,它只是一个文本编辑程序。  Vi是全屏幕文本编辑器,它没有菜单,只有命令

3、

4、Vi的基本概念

5、基本上vi可以分为三种状态各模式的功能区分如下: 1) 命令行模式(command mode) 控制屏幕光标的移动,字符、字或行的删除,移动复制某 区段及进入Insert mode下,或者到 last line mode。 2) 插入模式(Insert mode) 只有在Insert mode下,才可以做文字输入,按「ESC」键 可回到命令行模式。 3) 底行模式(last line mode) 将文件保存或退出vi,也可以设置编辑环境,如寻找字符 串、列出行号……

6、不过一般在使用时把vi简化成两个模式,就是将底行模式 (last line mode)也算入命令行模式command mode)。

三、实验概况(10分)

简述实验内容和基本设想

实验内容一

在linux环境下,编辑课件中源程序(注意程序的完整性)(包含源程序的开发环境截图),采用gcc编译该程序(要求分别采用-o和-O参数,并比较两者性能,编译指令截图),采用gdb进行调试,让程序运行到mult2函数的第一条语句(调试截图),运用objdump工具生成汇编程序(给出main函数的汇编程序截图)

\#include<stdio.h>

int main(void)

{

double counter;

double result;

double temp;

for(counter=0;counter<2000.0*2000.0*2000.0/20.0+2020;

counter+=(5-1)/4){

temp=counter/1979;

result=counter;

}

printf(Result is%lf\\n,result);

return 0;

}

实验一:第一部分:

实验内容:

在linux终端编辑源程序,分别采用-o和-O参数采用gcc编译该程序,生成可执行文件,在利用time命令比较两者运行性能。

实验设想:

-o 是没有对编译过程进行优化的。-O 参数是 gcc 对源代码进行基本 优化。这些优化在大多数情况下都会使程序执行的更快,时间更短。

实验一:第二部分:

实验内容:

对源文件进行编译之后,采用gdb进行调试,,设置断点,并实现利用 断点来调试程序,设置需要跟踪的变量。

实验设想:

设置断点后运行时,程序运行到断点会停止执行,设置观测变量便于了 解程序运行过程,直到收到继续执行的命令,从而实现对程序的调试。

实验一:第三部分:

实验内容:

首先对C源程序进行编译生成可执行二进制程序文件,然后利用运用objdump工具生成汇编程序,输出main函数的汇编程序。

实验设想:

Objbump命令生成汇编程序能清楚看到程序的底层体现。

实验内容二

在linux环境下,编辑书116页源程序(注意程序的完整性)(包含源程序的开发环境截图),采用gcc编译该程序(要求分别采用-o和-O参数,并比较两者性能,编译指令截图),采用gdb进行调试,让程序运行到mult2函数的第一条语句(调试截图),运用objdump工具生成汇编程序(给出main函数的汇编程序截图)

实验二:第一部分:

实验内容:

利用终端编辑书上两个源程序,分别采用-o和-O参数,采用gcc编译该程序,并利用time命令比较两者性能,注意是两个程序一起编译。

实验设想:

两个c源程序是工程形式存在的,对两个进行进行编译时也是一样的,然后-o 是没有对编译过程进行优化的。-O 参数是 gcc 对源代码进行基本优化。这些优化在大多数情况下都会使程序执行的更快。-O2是比-O更好的优化编译、连接。包含-O1的优化并增加了不需要在目标文件大小和执行速度上进行折衷的优化。编译器不执行循环展开以及函数内联。此选项将增加编译时间和目标文件的执行性能。

实验二:第二部分:

实验内容:

先利用gcc对源程序进行编译后,采用gdb进行调试,让程序运行到 mult2函数的第一条语句

实验设想:

设置断点后运行时,程序运行到断点会停止执行,设置观测变量便于了 解程序运行过程,直到收到继续执行的命令,从而实现对程序的调试。

实验二:第三部分:

实验内容:

首先对C源程序进行编译生成可执行二进制程序文件,然后利用运用objdump工具生成汇编程序,输出main函数的汇编程序。

实验设想:

Objbump命令生成汇编程序能清楚看到程序的底层体现。

实验内容三

在linux环境下,分别打印输出如下算法所需时间

分别设置不同优化参数,给出运行时间

实验三:第一部分:

实验内容:

在linux终端完善并输入保存上述两个算法的c源程序文件,然后gcc编译之后查看,两个不同的运算方式所运行的时间。

实验设想:

第一个算法是横向遍历,第二个算法是纵向遍历,实验设想是,横向遍历比纵向遍历更快。

实验三:第二部分:

实验内容:

对两个算法各运用-o和-O的方式进行编译,然后用time命令查看运行的时间,进行对比两个参数的优化效率。

实验设想:

不管是那种算法,-O 会对程序进行优化编译,会使程序的执行效率得到提高。

实验内容四(加分项)

任选高复杂度算法(具体算法自选,类型分为高计算量类型和高内存需求类型2类算法),通过设置不同优化参数,分析算法的运行效率

实验四:

实验内容:

编写一个冒泡排序,并进行大量数据的排序处理,实现高计算量的要求,然后在终端进行编译,查看各个优化参数的效果。为了效果更直观,把处理数据加大。

实验设想:

直观得到各个参数的优化效果,-O0是gcc的默认优化参数,表示不进行优化,-O1,具有优化效果,且效果明显,-O2 是优于-O1的优化参数,-O3是优化效果高于-O2的优化参数。

实验所用代码:

  1. \#include<stdio.h>
  2. \#include<stdlib.h>
  3. \#define N 104880
  4. void bubble\_sort(int a[],int n);
  5. //***一般实现***
  6. void bubble\_sort(int a[],int n)//n为数组a的元素个数
  7. {
  8. //一定进行N-1轮比较
  9. for(int i=0; i<n-1; i++)
    1. {
    1. //每一轮比较前n-1-i个,即已排序好的最后i个不用比较
    1. for(int j=0; j<n-1-i; j++)
    1. {
    1. if(a[j] > a[j+1])
    1. {
    1. int temp = a[j];
    1. a[j] = a[j+1];
    1. a[j+1]=temp;
    1. }
    1. }
    1. }

22. }

23. int main()

24. {

    1. int num[N];
    1. int m=0;
    1. for(m=N;m>0;m--)
    1. {
    1. num[m]=m*2+53;
    1. }
    1. bubble\_sort(num, N); //或者使用bubble\_sort\_better(num, N);
    1. //for(int i=0; i<N; i++)
    1. // printf("%d ", num[i]);
    1. printf("victory\n");
    1. return 0;

36. }

四、实验步骤(60-80分,每个实验内容20分)

实验一:第一部分

1,用Ubuntu编写书上代码,并命名t.c

2,用 默认方式不加优化的方式对c文件进行编译,并命名新执行文件a (gcc t.c -o a)

3,用time命令查看程序运行时间,1.093s,(time ./a)

4,用 -O基本优化方式对c文件进行编译,并命令新文件b (gcc -O t .c -o b)

5,用time命令查看程序运行时间,0.463s,改进了很多。(time ./b)

6,用 -O2优化方式对c文件进行编译,并命令新文件c (gcc -O2 t .c -o c)

7,用time命令查看程序运行时间,0.463s,具有一样的优化效果。(time ./c)

8,用 -O3优化方式对c文件进行编译,并命令新文件d (gcc -O t .c -o d)

9,用time命令查看程序运行时间,0.463s,具有一样的优化效果。(time ./d)

实验一:第二部分

1

1、对t.c保存为text.c

2、采用-g参数对text.c文件进行编译并命名中间生成文件为aa (gcc -g text.c -o aa)

3、

4、采用gdb命令对生成的中间文件进行调试 (gdb aa)

5、在程序第5行、第8行、第10行设置一个断点 (b 5)(b 8) (b 10)

6、输入run命令运行编译后的中间程序,程序运行到第一个断点停止运行

7、利用watch命令设置查看跟踪变量counter (watch counter)

8、输入continue命令程序继续往下运行,程序运行下一个断点,并给出counter变量运行后修改前后的值变化,

实验一:第三部分

1、首先用gcc命令对text.c进行编译,并对编译后的二进制可执行程序文件文件命名text,采用-g调试参数反汇编后的结果更明显。 (gcc -g -o text text.c)

2、采用objdump反汇编命令对编译生成的二进制文件text反汇编得到汇编代码,采用 -j 参数,可以输出指定段反汇编代码。($ objdump -j .text -Sl text|more)

3、查找输出main()函数的汇编程序。 ( /main())

实验二:第一部分

1、将书上的两段代码分别存入两个c文件,a.c 和 b.c 。

2、然后采用参数 -o 用gcc编译命令同时对两个文件进行编译,生成可执行文件 gg. ($ gcc a.c b.c -o gg)

3、利用time命令查看 -o 方式编译所用的时间,是0.001s。($ time ./gg)

4、然后采用参数 -O 用gcc编译命令同时对两个文件进行编译,生成可执行文件 gg. ($ gcc -O a.c b.c -o gg)

5、利用time命令查看 -O 方式编译所用的时间,还是0.001s,时间一样,效果不明显,。($ time ./gg)

6、继续采用参数 -O2 用gcc编译命令同时对两个文件进行编译,生成可执行文件 gg. ($ gcc -O2 a.c b.c -o gg)

7、利用time命令查看 -O2 方式编译所用的时间还是0.001s,说明程序复杂度低,看不出效果。($ time ./gg)

实验二:第二部分

1、采用-g 参数,利用gcc命令对c源文件进行编译生成可执行文件,并命名as。($ gcc -g a.c b.c -o as)

2、用gdb命令对生成的可执行文件as进行调试。($ gdb as)

3、输入list命令可以查看源代码的一部分 ((gdb) l)

4、对mult2函数设置第一个断点。((gdb) b mult2)

5、在程序第七行设置第二个断点。 ((gdb) b 7)

6、输入run命令进行运行, 程序停在第一个断点第7行。((gdb) r)

7、输入continue命令运行到第二个断点,程序停在mult2函数断点处。

实验二:第三部分

1、用 -g 参数用 gcc 命令对c源文件编译生成可执行程序,并命名为text。($ gcc -g a.c b.c -o text)

2、对生成的可执行文件程序利用objdump反编译命令对其进行反编译操作得到汇编代码。($ objdump -j .text -Sl text|more)

3、查找输出main函数的汇编程序。( /main())

实验三:第一部分

1、利用给的函数,编写完善a.c源程序文件,然后交换两个for循环后另外构造一个b.c源程序文件。

2、用 -o 的方式利用gcc命令对a.c 文件进行编译生成可执行文件aa。 ($ gcc a.c -o aa)

3、用time命令查看编译时间0.149s.(time ./aa)

4、用 -o 的方式利用gcc命令对b.c 文件进行编译生成可执行文件aa。 ($ gcc a.c -o aa)

5、用time命令查看编译时间0.109s,明显有改善。.(time ./aa)

实验三:第二部分

1、不使用优化参数,对源文件a.c进行编译,生成可执行文件并命名a。($ gcc a.c -o a)

2、利用time命令查看程序运行时间,0.114s.(time ./a)

3、使用-O 的基本优化参数对c源程序进行编译,得到可执行文件并命名a.($ gcc -O a.c -o a)

4、使用time命令查看程序运行时间,0.081s,有改善,但改善不多,不明显。($ time ./a)

5、不使用优化参数,对源文件b.c进行编译,生成可执行文件并命名b。($ gcc b.c -o b)

6、利用time命令查看程序运行时间,0.081s.(time ./a)

7、使用-O 的基本优化参数对c源程序进行编译,得到可执行文件并命名b.($ gcc -O b.c -o b)

8、使用time命令查看程序运行时间,0.084s,没有明显改善。($ time ./b)

实验四:

1、linux编写一个处理大量数据的冒泡排序算法,并命名mp.c

2、不加任何优化参数(默认为-O0)对mp.c文件进行编译形成可执行文件a,($ gcc mp.c -o a),并利用time命令查看程序运行时间为,10.393s。($ time ./a)

3、用-O 优化参数对源文件进行优化编译,生成可执行文件b,($ gcc -O mp.c -o b),并利用time命令对程序文件查看运行时间为4.975s,优化效果明显,优化后时间缩短一半。($ time ./b)

4、用-02 优化参数进行优化编译,生成可执行文件c,($ gcc -O2 mp.c -o c),并利用time命令对程序文件查看运行时间为4.963s,和-O的优化效果差不多。($ time ./c)

5、用-O3 优化参数对源文件进行优化编译,生成可执行文件d,($ gcc -O3 mp.c -o d),并利用time命令对程序文件查看运行时间为2.952s,优化效果比-O和-O2更显著,优化后再次缩短一半。($ time ./d)

6、用-O1 优化参数对源文件进行优化编译,生成可执行文件e,($ gcc -O1 mp.c -o e),并利用time命令对程序文件查看运行时间为5.028s,优化效果虽比前面几个差一点,但优化效果也是很显著,缩短一半。($ time ./e)

7、用-O0 优化参数对源文件进行优化编译,生成可执行文件f,($ gcc -O0 mp.c -o f),并利用time命令对程序文件查看运行时间为10.476s,可以看出和不加优化参数是一致的,因为他是关闭了所有优化选项的参数。($ time ./f)

五、实验分析(15分)

实验时的工作思路、设想、效果等综合分析

实验一:第一部分:

实验思路:

在linux终端编辑源程序,存储为c文件,然后分别采用-o和-O参数采用gcc编译该程序,生成可执行文件,在利用time命令比较两者运行性能。

实验设想:

-o 是没有对编译过程进行优化的。-O 参数是 gcc 对源代码进行基本 优化。这些优化在大多数情况下都会使程序执行的更快,时间更短。

效果分析:

-o 是不对编译过程进行优化的,-o是确定编译后的可执行文件的名称,如果没有-o,gcc就会给出预设的可执行文件a.out。而且gcc的默认优化参数睡-O0,是不具备优化功能的。-O 参数是 gcc 对源代码进行基本优化。这些优化在大多数情况下都会使程序执行的更快,时间更短

实验一:第二部分:

实验思路:

采用-g参数对源文件进行编译之后,采用gdb进行调试,,设置断点,并实现利用断点来调试程序,设置需要跟踪的变量。

实验设想:

设置断点后运行时,程序运行到断点会停止执行,设置观测变量便于了解程序运行过程,直到收到继续执行的命令,从而实现对程序的调试。

效果分析:

-g 选项是产生调试工具(GNU的gdb)所必要的符号信息,要想对编 译出的程序进行调试,就必须加入这个选项。实验一的程序比较简单,这里我设置了三个行断点,一个观测跟踪变量,来进行程序调试的分析。运行到第七行时,给出counter的前后值得变化.

实验一:第三部分:

实验思路:

加入 -g 选项,对C源程序进行编译生成可执行的二进制程序文件,然后利用运用objdump工具生成汇编程序,最后查找输出main函数的汇编程序。

实验设想:

Objbump命令生成汇编程序能清楚看到程序的底层体现。

效果分析:

通过objdump命令工具打印输出了main函数的机器代码的实现。

实验二:第一部分:

实验思路:

利用终端编辑书上两个源程序,分别采用-o和-O参数,采用gcc编译该程序,并利用time命令比较两者性能,注意是两个程序一起编译。

实验设想:

两个c源程序是工程形式存在的,对两个进行进行编译时也是一样的,放在一起进行编译,然后-o 是没有对编译过程进行优化的。-O 参数是 gcc 对源代码进行基本优化。这些优化在大多数情况下都会使程序执行的更快。-O2是比-O更好的优化编译、连接,包含-O1的优化,并增加了不需要在目标文件大小和执行速度上进行折衷的优化。

效果分析:

我这里使用了三种优化的方式进行了编译(无优化,-O , -O2),但是time命令给出的程序执行时间都是0.001s,是因为这里,实验二程序的复杂度低,执行低,所以三种优化效果不显著。

实验二:第二部分:

实验思路:

加入 -g选项,利用gcc对源程序进行编译后,采用gdb进行断点调试,让程序运行到 mult2函数的第一条语句

实验设想:

设置mult2函数为一个断点,设置断点后运行时,程序运行到断点会停止执行,设置观测变量便于了解程序运行过程,直到收到继续执行的命令,从而实现对程序的调试。

效果分析:

-g 选项是产生调试工具(GNU的gdb)所必要的符号信息,要想对编 译出的程序进行调试,就必须加入这个选项。实验二中的multi函数和main函数不在一个文件里面,无法通过list命令通过打印程序主体看行号设置断点,但可以直接break mult2 对mult2函数设置断点。运行程序之后,程序会一直运行直到运行到mult2函数停止运行,如截图,程序停在mult2函数,打印程序停留那一行的内容,显示程序现在运行到了第13行。

实验二:第三部分:

实验思路:

加入-g 选项,对C源程序进行编译生成可执行二进制程序文件,然后利用运用objdump工具生成汇编程序,输出main函数的汇编程序。

实验设想:

Objbump命令生成汇编程序能清楚看到程序的底层体现。

效果分析:

通过objdump命令工具打印输出了main函数的机器代码的实现。

实验三:第一部分:

实验思路:

在linux终端完善并输入保存上述两个算法的c源程序文件,然后gcc编译之后查看,两个不同的运算方式所运行的时间。

实验设想:

其实两种算法的区别就是,第一个算法是横向遍历,第二个算法是纵向遍历,实验设想是,横向遍历比纵向遍历更快。

效果分析:

纵向遍历用时0.149s。横向遍历用时0.109s,事情证明横向遍历比纵向遍历更快。

实验三:第二部分:

实验思路:

对两个算法各运用-o和-O的方式进行编译,然后用time命令查看运行的时间,进行对比两个参数的优化效率。

实验设想:

不管是那种算法,-O 会对程序进行优化编译,会使程序的执行效率得到提高。

效果分析:

-o 是不对编译过程进行优化的,-o是确定编译后的可执行文件的名称,而且gcc的默认优化参数睡-O0,是不具备优化功能的。-O 参数是 gcc 对源代码进行基本优化。这些优化在大多数情况下都会使程序执行的更快,时间更短。

第一个算法(也就是纵向遍历)不使用编译优化参数时,运行0.114s,用-O 优化选项后,运行用时0.081s,虽然不是很显著,但时间确实缩短了。在第二个算法中,两次运行时间所差无几,可能程序本身复杂度不高的缘故。

实验四:

实验思路:

自己编写一个冒泡排序(程序内容在前面),并进行大量数据的排序处理,实现高计算量的要求,然后在终端进行编译,查看各个优化参数的效果。为了效果更直观,把处理数据加大,同时这次把所有优化参数都测试了一下,看一下不同优化参数的直观效果。

实验设想:

直观得到各个参数的优化效果,-O0是gcc的默认优化参数,表示不进行优化,-O1,具有优化效果,且效果明显,-O2 是优于-O1的优化参数,-O3是优化效果高于-O2的优化参数。

效果分析:

此次试验效果直观,明了。第一次不使用优化参数用时10.393s。第二次使用-O 的优化选项,运行用时4.975s,时间缩短一半,效果显著。第三次使用 -O2的优化选项,用时4.963s,和-O 用时很接近。第四次使用 -O3 的优化选项,运行时间2.952s,再次缩短一半,这是优化最显著的参数。第五次使用了 -O1 的优化选项,用时5.028s,也是缩短一半的优化效果,。第六次使用 -O0 的优化选项(关闭优化功能),运行时间10.476s和第一次是一致的,也恰好验证了gcc在无优化参数时时-O0的无优化默认选项。

同时对这几个优化选项总结如下:

-O用来开启优化编译选项。

-O0 :默认模式,不做任何优化。

-O1:优化。该模式下对于一个大的函数或功能会花费更多的时间和内存。 在-O1下:编译会尝试减少代码体积和代码运行时间。但是并不执行会花费大量时间的优化操作。

-O2:在-O1 基础上进一步优化.GCC执行几乎所有支持的操作但不包括空间和速度之间权衡的优化。-O2优化等级下,并不执行循环展开和函数“内联”优化操作。与-O1比较该优化-O2将会花费更多的编译时间当然也会生成性能更好的代码。

-O3:更进一步优化。

六、实验总结(5分)

总结心得(包括遇到的困难,自己一些不成功的设计和设想)

总结:

此次四个实验使我理解了计算机如何进行对程序的编译,学会了linux操作系统命令的使用,对于计算机系统又有了更深层级的理解。

在实验一和实验二中,通过objdump命令反编译出程序的机器代码,看到了程序在编译后在机器中的存在方式,对于编译过程的认识就更直观。

在实验三种通过测试两种算法的执行时间解释了横向编译比纵向编译要更快,程序的细微差别,在机器上的执行就是不同的方式。

在实验四中收获最多,通过一个简单的冒泡算法的大量数据的测试,测试了所有编译优化选项的效果,对于各个优化选项也有了更深层次的认识,对各个优化参数的原理有了一定的了解。

标签: linux, 编译, 实验, 参数, 优化, gcc, 计算机系统, time

相关文章推荐

添加新评论,含*的栏目为必填