2017-2018-1 20155228 《信息安全系统设计基础》课程总结
一、每周作业链接汇总
第一周学习总结
简要内容
- 在linux环境中程序编译的过程逻辑
- 在linux环境中进行代码调试和程序调用
二维码
第二周课堂测试与课后作业
简要内容
- Makefile的使用
- 静态库和动态库的测试
- 编写myod实现Linux下od -tx -tc xxx的功能
二维码
第三周学习总结
简要内容
- 不同进制之间的转换
- 寻址和字节顺序
- 数据的位运算
- 有符号数与无符号数的转换
二维码
第四周学习总结
简要内容
- 用系统调用函数编写myod实现Linux下od -tx -tc xxx的功能
- 系统级I/O
- 编程myhead,mytail实现head,tail的功能
二维码
第五周学习总结
简要内容
- 指令集架构ISA
- 汇编语言指令
二维码
第六周学习总结&课下作业
简要内容
- 异常的种类
- 进程的创建和并发
- 信号机制
- 利用GDB对代码进行调试
- 通过对运算函数的测试理解数据在计算机中的存储方式
- 利用缓冲区溢出漏洞获取系统的管理员权限
二维码
第七周学习总结
简要内容
- ISA抽象的作用
- Y86-64指令和指令编码
- 流水线及其实现方式
二维码
第八周学习总结
简要内容
- 客户端-服务器编程模型
- 并发编程
二维码
第九周学习总结
简要内容
- 常见的存储技术
- 局部性原理
- 高速缓存的原理和应用
二维码
第十一周学习总结
简要内容
- 地址翻译
- 存储器映射
- 垃圾收集
二维码
第十三周学习总结
简要内容
- 进程和进程控制
- 基于进程的并发编程
二维码
第十四周学习总结
简要内容
- 虚拟内存
- 物理寻址和虚拟寻址
- 虚拟内存作为缓存的工具
- 虚拟内存作为内存管理的工具
- 虚拟内存作为内存保护的工具
- 动态存储器分配的方法
二维码
二、实验报告链接汇总
实验一 开发化境的熟悉
简要内容
- 参考bocsd目录中的脚本armc.sh, 分别用gcc和交叉编译器arm-none-linux-gnuenbi-gcc编译hello.c,用gcc编译的可执行文件命名linuxhello:gcc hello.c -o linuxhello; 用arm-none-linux-gnuenbi-gcc编译的命名为armhello: /usr/local/toolchain/toolchain4.3.2/bin/arm-none-linux-gnuenbi-gcc hello.c -o armhello
- 参考视频配置超级终端,用超级终端作为实验箱的显示终端,用ifconfig在超级终端中查看实验箱IP(目标机),在Ubuntu中(宿主机)中用ifconfig在命令行查看IP,用网线连接实验室台式机(或自己笔记本电脑)和ARM实验箱的网口NET1(最大屏旁边的),用ping命令保证目标机和宿主机能互相ping通
- 在超级终端中用“mkdir /arm_组员1学号_组员2学号” 建立实验箱中程序运行目录“arm_组员1学号_组员2学号”,在超级终端中运行“mount -t nfs -o nolock,宿主机IP:/home/linux/linux_组员1学号_组员2学号 /arm_组员1学号_组员2学号”通过NFS把宿主机中的“linux_组员1学号_组员2学号”,映射到目标机中的“/arm_组员1学号_组员2学号”,超级终端中运行"cd /arm_组员1学号_组员2学号",超级终端中运行"./armhello", 提交运行截图,并深入理解交叉编译
- 在目标机上重现上周“系统调用版的myod”,以静态库或共享库的方式在目标机上重现上周“系统调用版的myod”
二维码
实验二 固件程序设计
简要内容
- 安装MDK,JLink驱动,用系统管理员身分运行uVision4,破解MDK
- KEIL-MDK 中添加 Z32 SC-000 芯片库,完成LED实验和UART发送与中断接收实验
- KEIL-MDK 中添加 Z32 SC-000 芯片库,完成SM1加密实验
二维码
实验三 并发程序
简要内容
- 基于Linux Socket程序设计实现wc(1)服务器(端口号是你学号的后6位)和客户端,客户端传一个文本文件给服务器,服务器返加文本文件中的单词数
- 使用多线程实现wc服务器并使用同步互斥机制保证计数正确,上方提交代码,下方提交测试,对比单线程版本的性能,并分析原因
- 交叉编译多线程版本服务器并部署到实验箱中,PC机作客户端测试wc服务器
二维码
实验四 外设驱动程序设计
简要内容
- 学习资源中全课中的“hqyj.嵌入式Linux应用程序开发标准教程.pdf”中的第十一章
- 在Ubuntu完成资源中全课中的“hqyj.嵌入式Linux应用程序开发标准教程.pdf”中的第十一章的test试验
- 在实验箱中通过交叉编译完成test实验
二维码
实验五 通讯协议设计
简要内容
- 在Ubuntu中完成作业
- 在Ubuntu中实现对实验二中的“wc服务器”通过混合密码系统进行防护
二维码
三、代码托管链接和二维码
(一)截图 git log --pretty=format:"%h - %an, %ar : %s" 的结果
(二)代码量汇总提交statistics.sh的支持截图
(三)代码驱动的学习做到没有?
做到了代码驱动的学习。在学习教材内容的时候就把相关的代码编译运行一遍,以便加深对教材的理解。在设计算法的时候往往需要考虑代码该如何实现,一般通过百度相关的问题看别人用的是什么实现方式,然后对别人使用的函数进行学习,主要是看接口,具体的实现在一般的情况下可以不管。在看代码的时候通过百度确定函数的作用,然后画流程图分析编写代码的人解决问题的思路。
(四)加点代码,改点代码是理解的最好方式,参考编程的智慧,谈谈你的心得
在学习教材的过程中经常遇到看不懂的情况,把相关的代码编译运行,观察结果对理解教材有很大帮助,有时候对代码做适当修改观察结果能对某一个函数或者某一行代码有着更深刻的理解。在补做课堂实践内容的时候先看看别的同学或者别人的代码,主要是分析代码的编写思路是怎么样的。在有了清晰的思路过后,先尝试自己写代码,如果有困难的话就再看看别人具体是怎么写的,如果代码很复杂的话就直接复制粘贴过来逐行百度理解意思,然后再根据自己的需求进行修改。
(五) 实践上有什么经验教训
如果遇到编程实现某个功能完全没有思路或者在某一个问题完全不知道该怎么解决的时候,不妨看看别人是怎么做的,有时候因为个人思维的局限性,解决某个位会显得很麻烦或者说是很低效,参考别人的代码不是不劳而获而是学习别人的思考问题的方式。或者先做其他的部分,钻牛角是吃力不讨好的,经常时间用了很久但是效果却不好,所以说遇到问题一时半会确实没法解决的环境就先放一放,有时候长时间干一件事会产生很强的疲劳倦怠的感觉,所以先放一放反而能提高效率
(六)整体评价一下第1周作业中自己提出的问题是不是抓住了学习重点
并没有抓住了学习的重点,第一周作业中提出的问题只是简单翻翻书提出来的,并没有做深层的思考。
(七)回答一下第1周作业中自己提出的问题
第1章:如何理解信息=位+上下文
系统中所有的信息—包括磁盘文件、内存中的程序、内存中存放的用户数据以及网络上传送的数据,都是由一串比特表示的。区分不同数据对象的唯一方法是我们读到这些数据对象时的上下文。比如,在不同的上下文中,一个同样的字节序列可能表示一个整数、浮点数、字符串或者机器指令。
第2章:如何用位设置函数bis和位清除函数bic来实现按位|和^运算
Digital Equipment的VAX计算机没有布尔运算AND和OR指令,只有bis(位设置)和bic(位清除)这两种指令。两种指令的输入都是一个数据字x和一个掩码字m。它们生成一个结果z,z是由根据掩码m的位来修改x的位得到的。使用bis指令,这种修改就是在m为1的每个位置上,将z对应的位设置为1。使用bic指令,这种修改就是在m为1的每个位置,将z对应的位设置为O。
假设有两个函数bis和bic来实现位设置和位清除操作。只想用这两个函数,而不使用任何其他C语言运算,来实现按位|和^运算。
bis运算等价于布尔。R—如果x中或者m中的这一位置位了,那么z中的这一位就置位。另一方面,bic (x,m)等价于x&~m;实现只有当x对应的位为1且m对应的位为0时,该位等于1.由此,可以通过对bis的一次调用来实现|。为了实现^,可以利用以下属性x^y=(x&~y)|(~x&y)
/*Declarations of functions implementing operations bis and bic*/
int bis(int x, int m);
int bic(int x, int m);
/*Compute xly using only calls to functions bis and bic*/
int bool_or(int x, int y)
{
int result=bis(x,y);
return result;
}
/*Compute x"y using only calls to functions bis and bic*/
int bool_xor(int x, int y)
{
int result=bis(bic(x,y),bic(y,x));
return result;
}
第3章:区分MOV,MOVS,MOVZ
两类数据移动指令,在将较小的源值复制到较大的目的时使用。所有这些指令都把数据从源(在寄存器或内存中)复制到目的寄存器。MOVZ类中的指令把目的中剩余的字节填充为0,而MOVS类中的指令通过符号扩展来填充,把源操作的最高位进行复制。可以观察到,每条指令名字的最后两个字符都是大小指示符:第一个字符指定源的大小,而第二个指明目的的大小。
第4章:存储器和时钟的关系
组合电路从本质上讲,不存储任何信息。相反,它们只是简单地响应输人信号,产生等
于输入的某个函数的输出。为了产生时序电路(sequential circuit),也就是有状态并且在这个
状态上进行计算的系统,我们必须引人按位存储信息的设备。存储设备都是由同一个时钟控制
的,时钟是一个周期性信号,决定什么时候要把新值加载到设备中。考虑两类存储器设备:
时钟寄存器(简称寄存器)存储单个位或字。时钟信号控制寄存器加载输人值。
随机访问存储器(简称内存)存储多个字,用地址来选择该读或该写哪个字。随机访
问存储器的例子包括:1)处理器的虚拟内存系统,硬件和操作系统软件结合起来使
处理器可以在一个很大的地址空间内访问任意的字;2)寄存器文件,在此,寄存器
标识符作为地址。在IA32或Y86-64处理器中,寄存器文件有15个程序寄存器(%
rax一%r14)。
第5章:如何衡量程序的效率
我们引人度量标准每元素的周期数(Cycles Per Element, CPE),作为一种表示程序性能并指导我们改进代码的方法。CPE这种度量标准帮助我们在更细节的级别上理解迭代程序的循环性能。这样的度量标准对执行重复计算的程序来说是很适当的,例如处理图像中的像素,或是计算矩阵乘积中的元素。
第6章:存储技术和计算机软件的一些基本的和持久的属性
- 存储技术:不同存储技术的访问时间差异很大。速度较快的技术每字节的成本要比速度较慢的技术高,而且容量较小。CPU和主存之间的速度差距在增大。
- 计算机软件:一个编写良好的程序倾向于展示出良好的局部性。硬件和软件的这些基本属性互相补充得很完美。它们这种相互补充的性质使人想到一种组织存储器系统的方法,称为存储器层次结构(memory hierarchy),所有的现代计算机系统中都使用了这种方法。
第7章:CPU在指令的要求下的可以做哪些操作?
- 加载:从主存复制一个字节或者一个字到寄存器,以覆盖寄存器原来的内容
- 存储:从寄存器复制一个字节或者一个字到主存的某个位置。以覆盖这个位置上原来的内容
- 操作:把两个寄存器的内容复制到ALU,ALU对这两个字的做算术运算,并将结果存放到一个寄存器中,以覆盖该寄存器中原来的内容
- 跳转:从指令本身中抽取一个字并将这个字复制到程序计数器中以覆盖原来的值
第8章:数组指针、指针数组、函数指针、指针函数的区别
- 数组指针:重点在指针,表示它是一个指针,它指向的是一个数组。int (*fun)[8];
- 指针数组:重点在数组,表示它是一个数组,它包含的元素是指针 itn* fun[8];
- 函数指针:重点在指针,表示它是一个指针,它指向的是一个函数。eg: int (*fun)();
- 指针函数:重点在函数,表示它是一个函数,它的返回值是指针。 eg: int* fun();
第9章:动态存储器分配是怎么实现的
分配器有两种基本风格。两种风格都要求应用显式地分配块。它们的不同之处在于由哪个实体来负责释放已分配的块。
显式分配器(explicit allocator),要求应用显式地释放任何已分配的块。例如,C标准库提供一种叫做malloc程序包的显式分配器。C程序通过调用malloc函数来分配一个块,并通过调用free函数来释放一个块。C++中的new和delete操作符与C中的malloc和free相当。
隐式分配器(implicit allocator),另一方面,要求分配器检测一个已分配块何时不再被程序所使用,那么就释放这个块。隐式分配器也叫做垃圾收集器(garbage collec-tor),而自动释放未使用的已分配的块的过程叫做垃圾收集(garbage collection) 。例如,诸如Lisp, ML以及Java之类的高级语言就依赖垃圾收集来释放已分配的块。
第10章:操作系统是如何对各种I/O设备进行操作的
所有的I/O设备(例如网络、磁盘和终端)都被模型化为文件,而所有的输人和输出都被当作对相应文件的读和写来执行。这种将设备优雅地映射为文件的方式,允许Linux内核引出一个简单、低级的应用接口,称为Unix I/O,这使得所有的输人和输出都能以一种统一且一致的方式来执行
第11章:线程同步互斥的实现
信号量提供了一种很方便的方法来确保对共享变量的互斥访问。基本思想是将每个共享变量(或者一组相关的共享变量)与一个信号量、(初始为1>联系起来,然后用尸(、)和V(、)操作将相应的临界区包围起来。 以这种方式来保护共享变量的信号量叫做二元信号量(binary semaphore),因为它的值总是0或者1。以提供互斥为目的的二元信号量常常也称为互斥锁(mutex)。在一个互斥锁上执行尸操作称为对互斥锁加锁。类似地,执行V操作称为对互斥锁解锁。对一个互斥锁加了锁但是还没有解锁的线程称为占用这个互斥锁。一个被用作一组可用资源的计数器的信号量被称为计数信号量。
第12章:信号量操作如何确保临界区的互斥访问
每个状态都标出了该状态中信号量、的值。关键思想是这种尸和V操作的结合创建了一组状态,叫做禁止区(forbidden region),其中s<0
因为信号量的不变性,没有实际可行的轨迹线能够包含禁止区中的状态。而且,因为禁止区完全包括了不安全区,所以没有实际可行的轨迹线能够接触不安全区的任何部分。因此,每条实际可行的轨迹线都是安全的,而且不管运行时指令顺序是怎样的,程序都会正确地增加计数器值。从可操作的意义上来说,由尸和V操作创建的禁止区使得在任何时间点上,在被包围的临界区中,不可能有多个线程在执行指令。换句话说,信号量操作确保了对临界区的互斥访问。
(八)你有什么项目被加分,谈谈你的经验
好像没有被加分的项目呢
(九)你有什么项目被扣分,谈谈你的教训
好像也没有被扣分的项目呢
四、课程收获与不足
(一)自己的收获(投入,效率,效果等)
我感觉这学期花了很多时间在写代码上面,虽然没有写出很多不得了的程序来,但是感觉对计算机的各方面都有了更多的理解,从程序的编译运行到通过网络实现信息交流,从处理器调用执行命令的方式到各级存储对数据的记录方式,我对计算机系统的各方面的认识都有很大的提高。一学期写了很多个myxxx
比如说myod
或者mypwd
,我感觉在编写程序的时候,就是站在linux系统的角度去思考问题,如何满足使用者的需求。学会了用man -k | grep
查函数,感觉效率比百度要高,接口,简介都写得很简洁明了,很快就可以掌握其中的用法。刚开学的时候特别不喜欢用命令行,感觉没有图形界面那么直观觉得很不舒服,尤其是切换目录,复制文件的时候因为没有在图形页面里的明显变化感觉很奇怪,但是现在用Windows操作系统的时候范围有时候感觉不太方便,没有ls *.c
和tree
命令感觉有些不方便,没有了cp xxx
和mv xxx
就是很麻烦的事了,有时候还得像剥洋葱一样一层一层去翻。简而言之,在了解了linux的工作原理之后,使用linux也变得更加得心应手了。关于效率的问题我在下面的问题中来讲
(二)自己需要改进的地方
这学期比较大的问题就是一个效率的问题,感觉就是看书的速度不够快,我感觉一是没有很好地把握重点,看书的时候应该把重点的部分好好看一看,其他的部分就应该快一点,逐字逐句地仔细地读很快就形成疲劳,结果就是每一章前面的部分学得还不错,但是越往后面就越来越不清楚了,二是光看书不动手写代码导致很多知识无法理解,印在书上的代码有时候在计算机上跑一遍会有不一样的收获。
(三)如果有结对,写一下你提供的帮助或接受了什么帮助,并对老师提供参考建议
我和结对同学的主要合作就是在做实验的时候,一般是各自用自己的设备先做,遇到问题了再交流解决。平时的主要就是讨论代码实现某个功能的思路,我感觉我和结对同学的思方式有比较大的差异,这是一个很好的优势,有时候我先不到的问题他能想到,有时候他不知道的办法我知道,相同的功能有时候又不同的实现思路,做个比较对提高程序效率有很大帮助。
(四)给开学初的你和学弟学妹们的学习建议
在进行教材学习之前先去教学进程博客去看看学习目标,学习目标里面的内容就是看书的重点。如果觉得学习目标给的范围太宽泛的话就去看看更加详细的教材导读与每周考试重点。实验楼课程的实验的内容虽然不多但是一定要掌握好,对课堂测试有很大的帮助
写博客其实不用花太多时间抄书上的内容,只要把自己觉得重要或者困难的地方做个记录就可以了,自己看得懂就可以了。如果我们过了一段时间对某个知识点不清楚了,比如说某个函数该怎么使用,或者某个算法是怎么实现的,去翻博客可以很快回忆起来忘记的关键点的话,那么这篇博客就没有白写。如果写了很多博客摆在那里,在以后不想去看也看不懂的话,那还不如不要写。总的来说博客只是对学习的过程的记录,不是作为一样任务而专门去做的,每周学习的注意力应该更多的放在研究代码本身这个过程上,而不是写博客记录这个过程。
(五)如果重新学习这门课,怎么做才可以学的更好
少花点时间到写博客上面,多花点时间到学习教材和研究代码上面,就像我在前面说过的,博客只是对学习的过程的记录,不是作为一样任务而专门去做的。学习任务不要堆到周末再开始做,一是工作量比较大,只用周末做的话时间比较紧;二是容易形成倦怠心理,学习效率比较低。在周内有时间的时候就应该开始做这些事,至少先做一部分。写一个计划,今天用多长的时间看多少章节,明天在什么时候研究代码,按照计划学习的目的性比较强,效率也比较高。
五、问卷调查
(一)你平均每周投入到本课程多长时间?
阅读教材内容大约1-2小时,运行教材代码和完成实验楼的实验大约1-2小时,完成本周课下测试记录上周课下测试大约1小时,如果需要补课堂测试并完成额外题目的话大概需要3-4小时,写博客需要2-3小时,如果有实验的话得花1-2小时提前预习,写实验报告也要1-2小时,所以每周投入到学习课程的时间在5-16个小时之间。
(二)每周的学习效率有提高吗?
感觉每周的学习效率都差不多,没有明显的提高
(三)学习效果自己满意吗?
感觉还可以吧,虽然不是特别理想但是也在可接受的范围内
(四)课程结束后会继续一周至少一篇博客吗?(如果能做到,毕业时我把你的博客给你集结成一本书送给你作纪念)
不会,因为有的时候过了一周也没有什么值得记录或者还不足以做个记录的东西。
(五)你觉得这门课老师应该继续做哪一件事情?
希望继续维持课上测试和课下测试,并建议对分数做适当调整
适当提高课下测试在总成绩中所占的分数,提高到4分一次,按照每次课下测试成绩的排名给分,比如说排名前20%得4分,前40%得3分,前60%得2分,前80%得1分
适当降低课上测试在总成绩中所占的分数,降低到4分一次。
以上两条建议是希望以此鼓励同学在课下对教材进行仔细而深入的学习,课上测试所能考察的内容比较有限,只有几个题目,能考察的内容并不是很多,但是课下测试的题目比较多,可以对学习成果有更全面的考察。
(六)你觉得这门课老师应该停止做哪一件事情?
- 建议不要再要求单独把补做课上测试并完成额外题目的内容写成一篇博客,建议把每周学习总结和实验报告还有补做课上测试以及加分项目的博客合并到一篇博客中。以前开学的时候说两周写一篇博客,但是如果某一周有实验而且需要补做课上测试的话一周就需要写三篇博客,写三篇博客很容易让人形成倦怠情绪。其实可以把内容整合到一篇博客中,只要用一级标题分清栏目就可以了。其实还有一个解决办法,就是如果本周要写学习总结就不要设置课上测试,如果设置课上测试就不要写学习总结,本来学习总结和课上测试都是两周一次的,可能是这学期对课上测试和学习总结的时间安排出现撞车导致了一周要写三篇博客情况。
(七)你觉得这门课老师应该开始做什么新的事情?
- 建议新增每周一次的课下加分项目,4分一次,可以是学习其他教材的某一个章节的学习笔记,也可以是编程实现某个算法,将学习成果写进每周学习总结中,注明是加分项目,老师根据学习情况打1-4分,不做加分项目得0分,以此鼓励同学们在课下做更多深入性或者拓展性的学习。
(八)其他任意发挥
建议更新实验楼课程和教材导读与每周考试重点的内容,实验楼课程有好几个章节的内容都是空的,教材导读与每周考试重点也只有几个章节。
建议调整一下教学进程的时间日期,经常会遇到第几周和几月几号到几月几号对不上的情况。
建议每周周一提前在微信群里通知,或者直接在教学进程中本周写出是否有课上测试,方便大家提前做准备。
建议每两周或者每一个月统计公布一次成绩,方便同学们根据情况及时调整学习方式方法。
建议每学期开始就明确成绩构成,比如在开学的时候只说实验部分是15分,但是到了期末才知道每次实验提交截图1分,实验报告根据情况加分0-3分,期末实验测试15分,总分不超过15分。比如说开学的时候只说了期末有加分项目,但是到了期末的时候突然通知要增加课上考试。