20155306 2017-2018-1《信息安全系统设计》第二周课堂测试以及myod的实现

20155306 2017-2018-1《信息安全系统设计》第二周课堂测试以及myod的实现

第二周课堂测验:

(注:前两项在课堂已提交,在此不做详解)

第一项:

  1. 每个.c一个文件,每个.h一个文件,文件名中最好有自己的学号
  2. 用Vi输入图中代码,并用gcc编译通过
  3. 在Vi中使用K查找printf的帮助文档
  4. 提交vi编辑过程截图,要全屏,包含自己的学号信息

第二项:

  1. 用gcc 进行预处理,编译,汇编,链接vi输入的代码
  2. 生成的可执行文件中要有自己的学号
  3. 提交预处理,编译,汇编,链接,运行过程截图,要全屏,包含自己的学号信息

第三项:

  1. 用gcc -g编译vi输入的代码
  2. 在main函数中设置一个行断点
  3. 在main函数增加一个空循环,循环次数为自己学号后4位,设置一个约为学号一半的条件断点
  4. 提交调试过程截图(一定包含条件断点的),要全屏,包含自己的学号信息

关于GDB常用命令:

  • 安装:
sudo apt-get install gdb  

  • 源文件的某一行设置断点
break 行号  
  • 一个特定的函数设置断点
break 函数名  
  • break 函数名 (break可简写为 b)
break 行号 if 条件 
  • 运行跳转到断点
run
  • 观察变量,如果变量的值发生变化,程序就会停止
watch b 
  • 看变量的值或则单个变量的值,可以控制输出的格式
p i; 例如:输出八进制数:p/o i
  • 进入函数内部
s
  • 单步调试
n
  • 继续运行程序
continue
  • 自动显示一些变量
display
  • 退出gdb
q
  • 删除断点
delete 行号

第四项:

  1. 除了main.c外,其他4个模块(add.c sub.c mul.c div.c)的源代码不想给别人,如何制作一个mymath.a静态库?main.c如何使用mymath.a?
  2. 提交静态库生成和调用过程截图(一定包含条件断点的),要全屏,包含自己的学号信息。

步骤:
1.无论静态库,还是动态库,都是由.o文件创建的。首先将源程序.c通过gcc先编译成.o文件。

gcc -c add.c -o add.o
gcc -c sub.c -o sub.o
gcc -c mul.c -o mul.o
gcc -c div.c -o div.o

2.由.o文件创建静态库.静态库文件名的命名规范是以lib为前缀,紧接着跟静态库名,扩展名为.a。

ar rcs mymath.a add .o sub.o mul.o div.o

3.用gcc命令生成目标文件时指明静态库名,gcc将会从静态库中将公用函数连接到目标文件中。

gcc -static -o op1 main.o mymath.a

4.运行

./op1

遇到的问题:

1.在按部就班的输入一系列命令后,发现出现错误,如下显示:核心已转储,并且加减乘除结果不正确。

解决:在检查之后,发现main.c没有生成.o
文件,切记所有c文件都需变成o文件,不然无法创建静态库。

第五项:

  1. 除了main.c外,其他4个模块(add.c sub.c mul.c div.c)的源代码不想给别人,如何制作一个mymath.so共享库?main.c如何使用mymath.so?
  2. 提交共享库生成和调用过程截图(一定包含条件断点的),要全屏,包含自己的学号信息

步骤:
1.编译生成共享库

gcc -shared -fpic -o mymath.so add.c sub.c mul.c div.c

2.编译生成可执行文件

gcc -o op mian.c ./mymath.so

3.运行

./op

补充

1.什么是库

本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。

由于windows和linux的本质不同,因此二者库的二进制是不兼容的。

2.库的种类

linux下的库有两种:静态库和共享库(动态库)。

二者的不同点在于代码被载入的时刻不同。
静态库的代码在编译过程中已经被载入可执行程序,因此体积较大。
共享库的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小。

静态库的后缀是 .a

动态库的后缀是 .so

第六项:

1 写出编译上面vi编辑代码的makefile,编译出来的目标文件为testmymath, 只用显式规则就可以.

2 提交Make过程截图,要全屏,包含自己的学号信息

简单的说,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译。makefile带来的好处就是——“自动化编译”,感觉就是只需要一个make命令,整个工程完全自动编译。

Makefile的规则

目标 : 需要的条件 (注意冒号两边有空格)

命令 (注意前面用tab键开头!!!

testmymath:add.o sub.o mul.o div.o
        cc -o testmymath add.o sub.o mul.o div.o main.o
add.o : add.c head.h
        cc -c add.c
sub.o :sub.c head.h
        cc -c sub.c
mul.o :mul.c head.h
        cc -c mul.c
div.o :div.c head.h
        cc -c div.c
main.o :main.c head.h
        cc -c main.c 
~                                                                               
~                      

  
注:需要的条件就是生成目标所需要的文件或目标;命令就是生成目标所需要执行的脚本。

Myod

1 复习c文件处理内容

2 编写myod.c 用myod XXX实现Linux下od -tx -tc XXX的功能

  1. main与其他分开,制作静态库和动态库

  2. 编写Makefile

5 提交测试代码和运行结果截图, 提交调试过程截图,要全屏,包含自己的学号信息

6 在博客园发表一篇博客,重点写遇到的问题和解决过程

步骤:

1.理解od -tx -tc XXX的功能

od命令

通过指定该命令的不同选项可以以十进制、八进制、十六进制和ASCII码来显示文件。
语法:od [选项] 文件…

命令中各选项的含义:

  • A 指定地址基数,包括:
    d 十进制
    o 八进制(系统默认值)
    x 十六进制
    n 不打印位移值

  • t 指定数据的显示格式,主要的参数有:
    c ASCII字符或反斜杠序列
    d 有符号十进制数
    f 浮点数
    o 八进制(系统默认值为02)
    u 无符号十进制数
    x 十六进制数

2.三个.c文件

maim.c:文件的读入,判空,以及行号的设置
myod1.c:文本内容的输出
myod2.c:文本内容相应的十六进制ASCII码输出。

遇到的问题:

1.在head.h中,无法像myod1(FILE *f)这样来声明函数,出现如下图这样的提示:

解决:定义一个数组file[1000]="123.txt",再通过fopen打开123.txt。这样在head.h里声明的是char型,就不会有错误提示。

char file[1000]="123.txt";
char c,a[1000]={0};
FILE *f;
int i=0,m,line=0;
f=fopen(file,"r");

2.运行结果出现如下图,文本内容和ASCII出现错位:

解决:在myod1.c中,k=i-16出现错误。16个数一行,k为第一个数的序号,应该只减15。

3.编程时,行号随myod1.c的文本输出而输出。所以当最后一行文本内容结束时,行号也随之结束。但是od命令还有下一行的行号。

解决:在循环结束后,再输出一次line,这样才能多一行行号。

结果

除此之外,包括ASCII码输出时,要先printf一行空格,以保证文本和ASCII码相互对应。空格的个数要不断尝试,才能达到合适。

心得体会

这次任务中,前六个实践相对容易,百度一些资料,大部分是一些需要记忆的命令。但是编写Myod时,感受到自己C语言的薄弱,又重新打开课本,学习关于文件的知识,用了很多时间。虽然这次实验博客接近尾声,但是实践的相关知识还需要好好温习。如果时间允许的话,希望老师可以讲更多的内容,下课再依据上课内容实践,这样学习效果更好,印象更深刻!

参考资料

Makefile的编写

Linux 静态库&动态库调用

静态库的生成和使用

posted on 2017-10-01 21:34  20155306  阅读(187)  评论(3编辑  收藏  举报

导航