期中总结
期中总结
一、Chapter 1 Linux基础
man: man -k (等价于apropos)
1、$ man <command_name>来获得某个命令的说明和使用方式的详细介绍
2、你想查看 man 命令本身的使用方式,你可以输入:
man man
3、要查看相应区段的内容,就在 man 后面加上相应区段的数字即可,如:
$ man 3 printf
注:man printf和man 1 printf 功能等价。
4、man -k 常用来搜索,结合管道使用。
cd
1、进入上一级目录:
$ cd .. 2、进入你的“home”目录:
$ cd ~
或者 cd /home/<你的用户名> 3、使用 pwd 获取当前路径:
$ pwd
新建文件
1、使用 touch 命令创建空白文件
2、使用 mkdir(make directories)命令可以创建一个空目录,也可同时指定创建目录的权限属性
3、使用 -p 参数,同时创建父目录
4、使用cp(copy)命令复制一个文件或目录到指定目录。将之前创建的"test"文件复制
5、要成功复制目录需要加上-r或者-R参数,
6、使用rm(remove files or directories)命令,删除一个文件或目录:
7、使用mv(move or rename files)命令,移动文件(剪切)。将文件"file1"移动到"Documents"目录mv 源目录文件 目的目录
find
1、查找当前目录下所有目录的find命令是:
find . -type d
2、查找当前目录下2天前被更改过的文件:
find . -mtime +2 -type f -print
cheat
cheat是非常好用的“作弊”搜索工具,能够方便的告诉你你想要的内容。它提供显示Linux命令使用案例,包括该命令所有的选项和简短但尚可理解的功能。
cheat ls
- 查看用户
$ 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:为递归查找
信息:就是位+上下文。
Chapter 2 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(如果对第一个参数求值就能确定表达式的结果,那么就不会对第二个参数求值)
位运算:结果位向量
Chapter 3 程序的机器级表示 & 正则表达式
机器级代码
(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:
正则表达式
1、作用
验证是否匹配、查找、替换
2、规则
\ 特殊符号,表示后面的字符本身
[ ] 匹配其中任意字符,但每次匹配只匹配一个
[^ ] 匹配除其中的任意字符,每次匹配只匹配一个
{n} 次数修饰,重复n次,具体如下:
?= {0,1} += {1, } *= {0, } {m,n}:至少为m,至多为n
Chapter 4 处理器体系结构
程序员可见的状态
1、8个程序寄存器:%eax,%ecx,%edx,%ebx,%esi,%edi,%esp和%ebp。
2、条件码:ZF(零)、SF(符号)、OF(有符号溢出)
3、程序计数器(PC):存放当前正在执行的指令的地址
4、存储器:很大的字节数组,保存着程序和数据。Y86系统用虚拟地址来引用存储器的位置,硬件和操作系统软件联合起来将虚拟地址翻译成实际或物理地址。
5、状态码(stat):表明程序执行的总体状态。(异常处理)
字节
字节分为两个部分,每个部分4位:
高四位:代码部分,值域为0~0xB
第四位:功能部分,功能值只有在一组相关指令共用一个代码时才有用
Y86的顺序实现
1、取指:从存储器读取指令字节,地址为程序计数器(PC)的值。指令指示符字节两个四位部分,称为icode(指令代码)和ifun(指令功能)。vaIP(下一条指令的地址)=PC+已取出指令的长度。
2、译码:从寄存器文件读入最多两个操作数,得到valA和/或valB。
3、执行:算数逻辑单元(ALU)根据ifun的值执行指令指明的操作,计算存储器引用的有效地址,或者增加或减少栈指针。得到的值称为valE。也可根据条件码执行跳转。
4、访存:将数据写入存储器,或者从存储器读出数据。读出的值为valM。
5、写回:最多可以写两个结果到寄存器文件。
6、更新PC:将PC设置成下一条指令的地址。
实践:栈帧
○
Chapter 6 存储器层次结构
-
磁盘容量:
记录密度(位/英寸):磁道一英寸的段中可以放入的位数。
磁道密度(道/英寸):从盘片中心出发半径上一英寸的段内可以有的磁道数
面密度(位/平方英寸):记录密度与磁道密度的乘积。
○
-
磁盘操作:磁盘用读/写头来读写存储在磁性表面的位,而读写头连接到一个传动臂 一端,通过移动转动臂将读写头定位在磁道上的机械运动称为寻道。磁盘以扇区大小的块来读写数据,对扇区的访问时间有三个主要的组成部分:
-
寻道时间:转动臂将读/写头定位到包含目标扇区的磁道上所需时间。
-
旋转时间:驱动器等待目标扇区的第一个位旋转到读/写头下的时间。最大为
○
- 传送时间:读写并传送该扇区内容的时间。平均传送时间为:
○
局部性原理:一个编写良好的计算机程序倾向于引用邻近于其他最近引用过的数据项,或者最近引用过的数据项本身。
-
局部性有两种形式:时间局部性(temporal locality):在一个具有良好时间局部性的程序中,被引用过一次的存储器位置很可能在不远的将来再被多次引用;
-
空间局部性(spatial locality):在一个具有良好空间局部性的程序中,如果一个存储器位置被引用了一次,那么程序很可能在不远的将来引用附近的一个存储器位置。
存储器山
一个程序从存储系统中读数据的速率称为读吞吐量,或者读带宽,通常以兆字节每秒(MB/s)为单位。
读带宽的时间和空间局部性的二维函数称为存储器山。
参考资料:
1.教材:《深入理解计算机系统》
2.以前的博客http://www.cnblogs.com/bonjourvivi/
二、学习体会
不知不觉,半个学期已经过去了,开学初很惧的怕“胖黑书”——《深入理解计算机系统》也逐渐读了大半,从进入大学以来,我们学习了C语言、汇编、数据结构、java、EDA的与非门等等知识,但是我总是分散地学习各个知识点,并不明白这对我的编程水平以及我的专业信息安全有什么帮助,直到学习了本学期的深入理解计算机系统,作者在一章章中将操作系统、信息表示、汇编语言、数字电路、存储器结构等知识系统的联系在一起,让我能够回顾这两年学到的知识,把他们全部应用在理解计算机系统中。明白了前期知识铺垫的重要,也有了茅塞顿开的喜悦。
刚开始时,我不知道如何自主学习,面对内容繁多的一章以及实验内容,我无从下手,走马观花的阅读一遍并没有记住多少。从第三章开始,在老师的提醒下,看到优秀同学的学习方法,我开始有针对性的学习。首先是老师每周给出的学习重点,我会抄下来,一边比对、一边按章节学习。其次是划出重点课后题,先浏览遍题目,有针对性的去学习可以解答的内容,其他部分做大致了解,这样,当阅读完书后,我可以把习题做出来的时候,我知道自己大概学会了。还有我会在完成自己本周的学习内容、提交完博客后,去优秀博客看一看,看看他们是把那些知识作为重点,他们列出了哪些自己发现或总结的知识,而不仅仅是罗列书中的知识点。有了对比和研究后,我也有了自己的许多感悟。最后是在课堂小测后,我会仔细研究娄老师发布的每周检测解析,先是看我那里答错了,二是通过这些题归纳本章知识重点,再巩固一遍。
通过每周这样的学习,我有了很多进步,但是我也存在着一些不足。一是读书时不细致,偶尔存在着读不进去的情况,最后略读的结果就是不会有些细节的题不会,而且不会举一反三。在实践中或者作业中,需要用到书上的知识,我虽然已经阅读过一遍,但仍然不会解答。在栈帧的实践中,我就学习地很吃力,先是一点思路也没有,在同学的提点下,我比对书上P149页的栈帧结构图,然而实践中具体如何跳转我还是搞不懂,问了很多同学,经过他们耐心的讲解,我终于学懂了,也不禁在心中吐舌,我真是笨啊。二是自主学习能力较差,如今网络很发达,我的检索信息能力却不是很好,我自学能 力还是比较差,也不太会用网络信息来学习新知识。我认为综上我的缺点还是不勤学,我在这半个学期已经有了一些改观,我会在接下来的学习中更加严格督促自己,让自己勤于动脑、动手,这样才会在大学的自主学习中学得更好。