20155306 2017-2018-1《信息安全系统设计》第二周课堂测试以及myod的实现
第二周课堂测验:
(注:前两项在课堂已提交,在此不做详解)
第一项:
- 每个.c一个文件,每个.h一个文件,文件名中最好有自己的学号
- 用Vi输入图中代码,并用gcc编译通过
- 在Vi中使用K查找printf的帮助文档
- 提交vi编辑过程截图,要全屏,包含自己的学号信息
第二项:
- 用gcc 进行预处理,编译,汇编,链接vi输入的代码
- 生成的可执行文件中要有自己的学号
- 提交预处理,编译,汇编,链接,运行过程截图,要全屏,包含自己的学号信息
第三项:
- 用gcc -g编译vi输入的代码
- 在main函数中设置一个行断点
- 在main函数增加一个空循环,循环次数为自己学号后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 行号
第四项:
- 除了main.c外,其他4个模块(add.c sub.c mul.c div.c)的源代码不想给别人,如何制作一个mymath.a静态库?main.c如何使用mymath.a?
- 提交静态库生成和调用过程截图(一定包含条件断点的),要全屏,包含自己的学号信息。
步骤:
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文件,不然无法创建静态库。
第五项:
- 除了main.c外,其他4个模块(add.c sub.c mul.c div.c)的源代码不想给别人,如何制作一个mymath.so共享库?main.c如何使用mymath.so?
- 提交共享库生成和调用过程截图(一定包含条件断点的),要全屏,包含自己的学号信息
步骤:
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的功能
main与其他分开,制作静态库和动态库
编写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语言的薄弱,又重新打开课本,学习关于文件的知识,用了很多时间。虽然这次实验博客接近尾声,但是实践的相关知识还需要好好温习。如果时间允许的话,希望老师可以讲更多的内容,下课再依据上课内容实践,这样学习效果更好,印象更深刻!