20145227《信息安全系统设计基础》期中总结

20145227《信息安全系统设计基础》期中总结

一、 Linux基础

man: man -k (等价于apropos)

  • 你想查看 man 命令本身的使用方式,你可以输入:man man
  • 要查看相应区段的内容,就在 man 后面加上相应区段的数字即可,如: man 3 printf
  • man -k 常用来搜索,结合管道使用。

cd

  • 进入上一级目录: cd ..
  • 进入你的“home”目录:cd ~ 或者 cd /home/<你的用户名>
  • 使用 pwd 获取当前路径:pwd

新建文件

  • 使用 touch 命令创建空白文件
  • 使用 mkdir(make directories)命令可以创建一个空目录,也可同时指定创建目录的权限属性
  • 使用 -p 参数,同时创建父目录
  • 使用cp(copy)命令复制一个文件或目录到指定目录。将之前创建的"test"文件复制
  • 要成功复制目录需要加上-r或者-R参数,
  • 使用rm(remove files or directories)命令,删除一个文件或目录:
  • 使用mv(move or rename files)命令,移动文件(剪切)。将文件"file1"移动到"Documents"目录mv 源目录文件 目的目录

find

  • 查找当前目录下所有目录的find命令是:find . -type d
  • 查找当前目录下2天前被更改过的文件:find . -mtime +2 -type f -print

cheat

  • cheat是非常好用的“作弊”搜索工具,能够方便的告诉你你想要的内容。它提供显示Linux命令使用案例,包括该命令所有的选项和简短但尚可理解的功能。
  • 查看用户:$ who am i
  • 创建用户: 要创建用户需要 root 权限,要用到 sudo 这个命令。使用这个命令有两个大前提,一是要知道当前登录用户的密码,二是当前用户必须在 sudo 用户组。
  • 用户组: 在 Linux 里面每个用户都有一个归属(用户组),用户组简单地理解就是一组用户的集合,它们共享一些资源和权限,同时拥有私有资源。
  • 查看用户属于的用户组:
     $ groups 用户名 或 $ cat /etc/group | sort
     $ sudo adduser 用户名

  • 将其它用户加入 sudo 用户组:
     $ su 当前用户	//获得root权限
     $ groups 待添加用户
     $ sudo usermod -G sudo 待添加用户	//将用户添加到sudo用户组
     $ groups 待添加用户

  • 删除用户: sudo deluser 待删除用户 --remove-home

grep

  • 查找宏 STDIN_FILENO 的值的命令是:grep -nr XXX /usr/include
  • 该语句可以用来查找关键字,全文搜索,并且可以直接查找文件内的内容。其中:
     n:为显示行号
     r:为递归查找

信息:就是位+上下文。

二、 Vim使用方法

K

  • 大写“K”可以用来查找函数的帮助信息:查看 man page,命令模式下,将光标放在函数名上,按"K"可以直接察看 man page。

几个设置

:set nu 显示行号
:set ai 自动缩行
:set ts=4 设置一个 TAB 键等于几个空格

  • 移动光标
     [[ 转到上一个位于第一列的"{"
     ]] 转到下一个位于第一列的"{"
     { 转到上一个空行
     } 转到下一个空行
     gd 转到当前光标所指的局部变量的定义

GCC

  • 预处理:gcc –E hello.c –o hello.i;gcc –E调用cpp
  • 编 译:gcc –S hello.i –o hello.s;gcc –S调用ccl
  • 汇 编:gcc –c hello.s –o hello.o;gcc -c 调用as
  • 链 接:gcc hello.o –o hello;gcc -o 调用ld

GDB

  • gdb programm(启动GDB)
  • b 设断点(要会设4种断点:行断点、函数断点、条件断点、临时断点)
  • run 开始运行程序
  • bt 打印函数调用堆栈
  • p 查看变量值
  • c 从当前断点继续运行到下一个断点
  • n 单步运行
  • s 单步运行
  • quit 退出GDB

模式转换

  • 在普通模式中,有很多方法可以进入插入模式。比较普通的方式是按a(append/追加)键或者i(insert/插入)键。
  • 在插入模式中,可以按ESC键回到普通模式。
  • 在命令行模式中可以输入会被解释成并执行的文本。例如执行命令(:键),搜索(/和?键)或者过滤命令(!键)。在命令执行之后,Vim返回到命令行模式之前的模式,通常是普通模式。

删除命令

     dd  删除整行
     dw  删除一个单词(不适用中文)
     d^  删除至行首
     dG  删除到文档结尾处

信息存储

  • gcc -m32 可以在64位机上生成32位的代码

字节顺序表示方法

  • 小端是“高对高,低对低”
  • 大端是“高对低,低对高”

运算

  • 逻辑运算:结果0或1(如果对第一个参数求值就能确定表达式的结果,那么就不会对第二个参数求值)
  • 位运算:结果位向量

三、 程序的机器级表示 & 正则表达式

机器级代码

(1)ISA
(2)机器级程序使用的存储器地址是虚拟地址

获得汇编代码

  • gcc -S xxx.c -o xxx.s 获得汇编代码
    eg:unix> gcc -01 -S code.c
  • objdump -d xxx 反汇编;
    eg:unix> objdump -d code.o

数据传送指令:

(1)MOV类指令
定义:将数据从一个位置复制到另一个位置,将源操作数的值复制到目的操作数。

     movb(传送字节)
     movw(传送字)
     movl(传送双字)

(2)PUSH&POP指令

PUSH:将数据压入程序栈中
POP:从程序栈中弹出数据

算术操作——移位

     SAL 算术左移
     SHL 逻辑左移
     SAR 算术右移(补符号位)
     SHR 逻辑右移(补0)

条件码寄存器及常用指令

  • 常用的条件码:
      CF:进位标志
      ZF:零标志
      SF:符号标志
      OF:溢出标志

  • 常见指令:
      LEAL:不改变条件码寄存器
      XOR:进位标志和溢出标志会设置成0
      INC:设置溢出和零标志
      DEC:设置溢出和零标志
      CMP:根据操作数之差设置条件码
      SUB:设置条件码,更新寄存器
      TEST:改变目的寄存器的值

循环

1、do-while循环

  • do-while语句的通用形式:
do
body-statement
while(test-expr);

  • 可翻译成如下:
loop:
body-statement
t = test-expr;
if(t)
   goto loop;

2、while循环

  • while语句的通用形式:
while (test-expr)
body-statement

  • GCC采用的方法,是使用条件分支,需要时省略循环体的第一次执行:
if(!test-expr)
    goto done;
do
    body-statement
    while(test-expr);
done:

  • 接下来,这个代码可直接翻译成goto代码:
    t = test-expr;
     if(!t)
    goto done:
loop:
    body-statement
    t = test-expr;
    if(t)
    goto loop;
done:

3、for循环

  • for循环的通用形式:
for(init-expr;test-expr;update-expr)
body-statement

汇编结构:

    init-expr
    t=test-expr;
    if(!t)
    goto done;
loop:

    body-statement
    update-expr;
    t=test-expr;
    if(t)
        goto loop;
    done:

关于栈帧的gdb命令:

1、backtrace/bt n

打印当前的函数调用栈的所有信息。
n是一个正整数,表示只打印栈顶上n层的栈信息。
-n表一个负整数,表示只打印栈底下n层的栈信息。

2、frame n

n为栈中的层编号,是一个从0开始的整数
比如:frame 0,表示栈顶,frame 1,表示栈的第二层。
该指令是移动到n指定的栈帧中去,并打印选中的栈的信息。
如果没有n,则打印当前帧的信息。

3、up n

表示向栈顶移动n层
可以不打n,表示向上移动一层。

4、down n

表示向栈底移动n层
可以不打n,表示向下移动一层。

第五周实验编写的源代码如下:

注释了栈帧情况的汇编代码:

分析:

正则表达式

1、作用

  • 验证是否匹配、查找、替换

2、规则


\ 特殊符号,表示后面的字符本身
[ ] 匹配其中任意字符,但每次匹配只匹配一个
[^ ] 匹配除其中的任意字符,每次匹配只匹配一个
{n} 次数修饰,重复n次,具体如下:
    ?= {0,1}
    += {1, }	
    *= {0, }
    {m,n}:至少为m,至多为n

四、处理器体系结构

程序员可见的状态

  • 1、8个程序寄存器:%eax,%ecx,%edx,%ebx,%esi,%edi,%esp和%ebp。
  • 2、条件码:ZF(零)、SF(符号)、OF(有符号溢出)
  • 3、程序计数器(PC):存放当前正在执行的指令的地址
  • 4、存储器:很大的字节数组,保存着程序和数据。Y86系统用虚拟地址来引用存储器的位置,硬件和操作系统软件联合起来将虚拟地址翻译成实际或物理地址。
  • 5、状态码(stat):表明程序执行的总体状态。(异常处理)

字节

  • 字节分为两个部分,每个部分4位:
    (1)高四位:代码部分,值域为0~0xB
    (2)第四位:功能部分,功能值只有在一组相关指令共用一个代码时才有用

Y86的顺序实现

  • 1、取指:从存储器读取指令字节,地址为程序计数器(PC)的值。指令指示符字节两个四位部分,称为icode(指令代码)和ifun(指令功能)。vaIP(下一条指令的地址)=PC+已取出指令的长度。
  • 2、译码:从寄存器文件读入最多两个操作数,得到valA和/或valB。
  • 3、执行:算数逻辑单元(ALU)根据ifun的值执行指令指明的操作,计算存储器引用的有效地址,或者增加或减少栈指针。得到的值称为valE。也可根据条件码执行跳转。
  • 4、访存:将数据写入存储器,或者从存储器读出数据。读出的值为valM。
  • 5、写回:最多可以写两个结果到寄存器文件。
  • 6、更新PC:将PC设置成下一条指令的地址。

五、存储器层次结构

  • 磁盘容量:

  • 磁盘操作:磁盘用读/写头来读写存储在磁性表面的位,而读写头连接到一个传动臂 一端,通过移动转动臂将读写头定位在磁道上的机械运动称为寻道。磁盘以扇区大小的块来读写数据,对扇区的访问时间有三个主要的组成部分:

  • 寻道时间:转动臂将读/写头定位到包含目标扇区的磁道上所需时间。

  • 旋转时间:驱动器等待目标扇区的第一个位旋转到读/写头下的时间。最大为

  • 传送时间:读写并传送该扇区内容的时间。平均传送时间为:

  • 局部性原理:一个编写良好的计算机程序倾向于引用邻近于其他最近引用过的数据项,或者最近引用过的数据项本身。

  • 局部性有两种形式:
    (1)时间局部性(temporal locality):在一个具有良好时间局部性的程序中,被引用过一次的存储器位置很可能在不远的将来再被多次引用;
    (2)空间局部性(spatial locality):在一个具有良好空间局部性的程序中,如果一个存储器位置被引用了一次,那么程序很可能在不远的将来引用附近的一个存储器位置。

  • 存储器山

  • 一个程序从存储系统中读数据的速率称为读吞吐量,或者读带宽,通常以兆字节每秒(MB/s)为单位。

  • 读带宽的时间和空间局部性的二维函数称为存储器山。

易错题目集

  • grep 填空:查找宏 STDOUT_FILENO 的值的命令是(grep -nr STDOUT_FILENO /usr/include)
  • ch01 填空:存储层次结构的主要思想是一层上存储器作为低一层存储器的(高速缓存)
  • CH02 填空:(Shannon 或香农)建立了布尔代数和数字逻辑之间的联系。
  • 四位数0xD 截断为3位数,解释为无符号数的截断后值是( 5 )
  • 4.2 Y86中 5054fdffffff 对应的汇编语句是( mrmovl –3(%esp), %ebp )
  • 判断:SRAM和DRAM掉电后均无法保存里面的内容。( ok )
  • CH03 填空:Linux汇编中,销毁栈帧的语句是(movl %ebp,%esp popl %ebp 或leave)
  • CH03 填空: jz/jnz指令中跳转条件是由(ZF)决定的。

自己的收获

不知不觉,半个学期已经过去了,《深入理解计算机系统》也逐渐读了大半。进入大学以来,我们先后学习了C语言、数据结构、汇编、java等等知识,但是我总是分散地学习各个知识点,并不明白这对我的编程水平以及我的专业知识有什么帮助,直到学习了本学期的深入理解计算机系统,作者在一章章中将操作系统、信息表示、汇编语言、数字电路、存储器结构等知识系统的联系在一起,让我能够回顾这两年学到的知识,把他们全部应用在理解计算机系统中。这是第一个大的收获。另外一个大的收获是:自己独立学习的能力提升了很多。从一开始Java的学习到这学期的深入理解计算机系统,我看着厚厚的教材不知从何下手,每次只是走马观花的看看教材,记住的很少,真正理解的更加少。后来我开始看每周老师评出的优秀博客以及学长学姐们的博客,看他们是如何归纳每周的重点的,然后我会按照老师的要求一步一步去做。连续几周之后,感觉自己抓重点的能力以及自主学习的能力提升了不少。最后是在每周课堂小测后,我会仔细研究老师发布的每周检测解析,先是看我哪里答错了,为什么错;然后通过这些题归纳本章知识重点,再巩固一下知识。通过每周这样的学习,我有了很多进步。

自己的不足

虽然自己有了一些进步,但还是存在一些不足。第一是读书时不细致,静不下来,有时候一些内容读不进去,结果就是不会解答某些题,特别是有些细节的题。而且我不会举一反三,在作业中,有些书上的知识,我虽然已经阅读过一遍,但仍然不会解答。有些时候经过别人的提醒,才能联想到某个前面看过的知识,然后解答出来。看着答案,我能看懂为什么应该这样解答,但是给我一个全新的题,我却没有一个很好的解题思路。第二就是我还是不够勤学,很多时候都要跟着别人的步伐走。遇到某个问题我习惯于寻求学霸和同学的帮助,而不是先自己想想、找找解决办法。我觉得我这一点特别不好,以后我会改正。从学java开始到现在,我已经有了一些改观。我会在接下来的学习中更加严格督促自己,让自己勤于动脑、动手,这样才会在大学的自主学习中学得更好。

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 0 2/2 20/20
第二周 100/100 1/3 20/40
第三周 200/300 1/4 22/62
第五周 200/500 1/5 22/84
第六周 274/774 1/6 22/106
第七周 127/901 2/8 22/128
第八周 50/951 2/10 22/150

参考资料

posted @ 2016-11-06 15:41  20145227鄢曼君  阅读(273)  评论(5编辑  收藏  举报