(一)Linux基础
一、常用命令
1.man -k:
man -k k1 | grep k2 | grep 2
搜索同时含有k1和k2,且属于系统调用,最后的数字意味着帮助手册中的区段,man手册共有8个区段,最常用的是123,含义如下:
(1)Linux
(2)系统调用
(3)c语言
2.grep -nr:
n:为显示行号 r:为递归查找
3.cheat:
cheat是作弊,小抄的意思。
二、常用工具
1.vim命令:
(1)常用的进入、保存和退出指令:
进入:vim 文件名
保存: :w
退出: :q
(2)常用动作:
删除:dd删除整行
复制:yy复制整行
粘贴:p
2.gcc:
(1)符号
-c 只编译不链接,生成目标文件.o
-S 只编译不汇编,生成汇编代码
-E 只进行预编译,不做其他处理
-g 在可执行程序中包含标准调试信息
-o file 将file文件指定为输出文件
-v 打印出编译器内部编译各过程的命令行信息和编译器的版本
-I dir 在头文件的搜索路径列表中添加dir目录
(2)编译
编译过程
预处理: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** 创建可执行目标文件
3.gdb
(1)基本命令
gdb programm(启动GDB)
l 查看所载入的文件
b 设断点
info b 查看断点情况
run 开始运行程序
bt 打印函数调用堆栈
p 查看变量值
c 从当前断点继续运行到下一个断点
n 单步运行(不进入)
s 单步运行(进入)
quit 退出GDB
三、正则表达式
1.作用:
- 验证是否匹配
- 查找
- 替换
2.规则:
- \ 特殊符号,表示后面的字符本身
- [ ] 匹配其中任意字符,但每次匹配只匹配一个
- [^ ] 匹配除其中的任意字符,每次匹配只匹配一个
-
{n} 次数修饰,重复n次,具体如下:
3.匹配方法:
- ^ 从字符串开始的地方匹配
- $ 从字符串结束的地方匹配
- | 可以匹配左或者右
-
() 1.次数修饰中,可以表示当做整体;2.结果中,可以表示单独表示
四、静态库与动态库
1.静态库:
(1)创建静态库:
gcc -c add.c mul.c
ar rcs lib.a add.o mul.o
(2)创建静态库的可执行文件
gcc -02 -c main.c
gcc -static -o p main.o ./lib.a
2.动态库:
(1)构建动态库
gcc -shared -fPIC -o lib.so add.c mul.c
(2)链接程序
gcc -o p main.c ./lib.so
(二)信息的表示和处理
一、浮点数
浮点表示对形如V=x X (2^y)的有理数进行编码,适用于:
非常大的数字 非常接近于0的数字 作为实数运算的近似值
1.二进制小数
小数的二进制表示法只能表示那些能够被写成x X (2^y)的数,其他的值只能近似的表示。
(1)权重
以小数点为界:
左边第i位,权重为2的i次幂
右边第i位,权重为1/2的i次幂
2.
IEEE浮点表示
(1)IEEE浮点标准:
用V=(-1)^s X 2^E X M 来表示一个数:
符号:s决定这个数是正还是负。0的符号位特殊情况处理。
阶码:E对浮点数加权,权重是2的E次幂(可能为负数) 尾数:M是一个二进制小数,范围为1~2-ε或者0~1-ε(ε=1/2的n次幂)
(2)编码规则
单独符号位s编码符号s,占1位
k位的阶码字段exp编码阶码E
n位小数字段frac编码尾数M(同时需要依赖阶码字段的值是否为0)
(3)两种精度
- 单精度(float),k=8位,n=23位,一共32位;
- 双精度(double),k=11位,n=52位,一共64位。
二、舍入
舍入运算:找到和数值x最接近的匹配值x',可以用期望的浮点形式表示出来。
IEEE浮点格式定义了四种不同的舍入方法:
1.向偶舍入(默认方法)
即:将数字向上或向下舍入,是的结果的最低有效数字为偶数。
能用于二进制小数。
2.向零舍入
即:把整数向下舍入,负数向上舍入。
3.向下舍入
正数和负数都向下舍入。
4.向上舍入
正数和负数都向上舍入。
三、浮点运算
1.浮点加法
- 浮点加法是可交换的
- 浮点加法不具结合性
- 大多数值的浮点加法都有逆元,除了无穷和NaN。
- 浮点加法满足单调性
2.浮点乘法
- 浮点乘法是可交换的
- 浮点乘法不具有结核性
- 浮点乘法的单位元为1.0
- 浮点乘法在加法上不具备分配性
(三)程序的机器级表示
一、程序编码
gcc -01 -o p p1.c
- -01 表示使用第一级优化。优化的级别与编译时间和最终产生代码的形式都有关系,一般认为第二级优化-02 是较好的选择。
- -o 表示将p1.c编译后的可执行文件命名为p
GCC将源代码转化为可执行代码的步骤:
C预处理器——扩展源代码-生成.i文件
编译器——产生两个源代码的汇编代码-——生成.s文件
汇编器——将汇编代码转化成二进制目标代码——生成.o文件
链接器——产生可执行代码文件
二、访问信息
1.操作数指示符
(1)操作数:指示出执行一个操作中要引用的源数据值,以及放置结果的目标位置。
a.操作数的三种类型
- 立即数
- 寄存器
- 存储器
(2)结果存放的两种可能
- 寄存器中
- 存储器中
2.数据传送指令
(1)mov指令
a.功能
把一个字节(字)操作数从源SRC传送至目的地DST
b.格式
MOV DST,SRC
(2) push&pop
a.压栈push
功能:把数据压入到栈上
b.出栈pop
功能:弹出数据
都只有一个操作数。
3.数据传送示例
(1)c操作符*执行指针的间接引用。
(2)c语言中的指针其实就是地址,间接引用指针就是将该指针放在一个寄存器中,然后在存储器引用中使用这个寄存器
(3)局部变量通常保存在寄存器中,而不是存储器
三、过程
1.栈帧结构
栈用来传递参数、存储返回信息、保存寄存器,以及本地存储。
(1)栈帧:
为单个过程分配的那部分栈帧。
(2)两个指针:
最顶端的栈帧以两个指针界定:
寄存器%ebp-帧指针
寄存器%esp-栈指针
栈指针可移动,所以信息访问多相对于帧指针。
2.转移过程
(1)call指令
- 和转移指令相似,同样分直接和间接,直接调用的目标是标号,间接调用的目标是*后面跟一个操作数指示符,和JMP一样。
- 指令的效果是将返回地址入栈,并跳转到被调用过程的起始处。返回地址是还在程序中紧跟在call后面的那条指令的地址,然后就会用到ret了。
(2)ret指令
ret指从栈中弹出地址,并跳转到这个位置。
(3)leave指令
这个指令可以使栈做好返回的准备,等价于:
movl %ebp,%esp
popl %ebp
(四)处理器体系结构
一、Y86指令集体系结构
1.Y86指令
Y86指令集基本上是IA32指令集的一个子集,只包括四字节整数操作,寻址方式比较少,操作也较少。
(1)movl指令:
- 分成了四个不同的指令:irmovl,rrmovl,mrmovl和rmmovl.
- 源可以是立即数(i),寄存器(r)或存储器(m)。
目的可以是寄存器(i)或存储器(m)。
指令名字的第一个字母就表明了源的类型,指令名字的第二个字母就指明了目的类型。
注意:
- 这里的存储器引用方式是简单的基址和偏移量形式,寻址方式不支持第二变址寄存器和任何寄存器值的伸缩。
- 两个操作数不能都是来自存储器,也不允许将立即数传送到存储器。
(2)四个整数操作指令
- addl 加
- subl 减
- andl 乘
- xorl 除
a.它们只对寄存器数据进行操作(I32还允许对存储器数据进行操作)。
b.这些指令会设置三个条件码:ZF,SF和OF(零,符号和溢出)。
(3)七个跳转指令
jmp,jle,jl,je,jne,jge和jg。
(4)6个条件传送码
cmovle,cmovl,cmove,cmovne,cmovge和cmovg.
只有当条件码妈祖所需要的约束时,才会更新目的寄存器的值。
(5)call,ret
call指令将返回地址入栈,然后跳到目的地址。ret从这样的过程调用中返回。
(6)pushl和popl
实现了入栈和出栈。
(7)halt
a.停止指令的执行。
b.执行halt指令会导致处理器停止,并将状态码设置为HLT。
2.Y86异常
(1)状态码Stat
a.描述程序执行的总体状态。
b.AOK 正常操作
- HLT 处理器执行halt指令
- ADR 遇到非法地址
- INS 遇到非法指令
3.一些Y86指令的详情
两个特别的指令:pushl和popl 通常有两种约定
(1)压入%esp的原始值。
(2)压入减去4的%esp得出值。
二、Y86的顺序实现
SEQ处理器
1.将处理组织成阶段
(1)阶段
- 取指:
- 译码:
- 执行:
- 访问;
- 写回:
- 更新PC:
详细内容见书P251。
(2)OPl(整数和逻辑运算),rrmovl(寄存器-寄存器传送)和irmovl(立即数-寄存器传送)类型的指令所需的处理。见书P252 图4-18
(3)rmmovl和mrmovl所需要的处理。见书 P253 图4-19
(4)处理pushl和popl指令所需的步骤。见书 P254 图4-20
(5)跳转,call和ret三类控制转移指令的处理。 见书P256 图4-21
(五)存储器层次结构
一、存储技术
1.磁盘存储
(1)磁盘构造
a.由盘片构成,每个盘片有两面或者称为表面,表面覆盖着磁性记录材料,盘中央有一个可以旋转的主轴,使得盘片以固定的旋转速率旋转,磁盘通常包含一个或者多个这样的盘片,冰封装在一个密封的容器内。
b.每个表面由一组称为磁道的同心圆组成的。每个磁道被划分为一组扇区,每个扇区包含相等数量的数据位(512字节),扇区之间由一些间隙分隔开,间隙间不存储数据位。间隙存储用来标识扇区的格式化位。
(2)磁盘容量
a.最大容量(容量):一个磁盘上可以记录的最大位数。
b.决定因素:
- 记录密度:磁道一英寸的段中可以放入的位数。
- 磁道密度:从盘片中心出发半径上一英寸的段内可以有的磁道数。
- 面密度:记录密度与磁道密度的乘积。
c.公式:
(3)磁盘操作
a.磁盘是以扇区大小的块来读写数据。
b.访问时间:
- 寻道时间:移动传动臂所需的时间。通常3~9ms,一次寻道的最大时间可达20ms。
- 旋转时间:依赖于当读/写头到达目标磁道时盘面的位置和磁盘的旋转速度。
最大旋转延迟:T(max rotation) = (1/RPM)*(60secs/1min)
平均旋转时间:T(avg rotation)=1/2T(max rotation)
l 传送时间:一个扇区的传送时间依赖于旋转速度和每条磁道的扇区数目。
T(avg transfer)= (1/RPM)*(1/(平均扇区数/磁道))*(60secs/1min)
注意:
- 访问一个磁盘扇区中512个字节的时间主要是寻道时间和旋转延迟。
- 寻道时间和旋转延迟大致相等,估计磁盘访问时间可将寻道时间x2
(4)逻辑磁盘块
a.一个B个扇区大小的逻辑快的序列,编号为0,1,….,B-1。
b.磁盘中有一个小的硬件/固件设备,称为磁盘控制器。维护着逻辑块号和实际磁盘扇区之间的映射关系。
二、局部性
两种形式:时间局部性和空间局部性
1.对程序数据引用的局部性
(1)顺序引用模式:步长为1的引用模式。
(2)c数组在存储器中是按照行顺序来存放的。
2.取指令的局部性
(1)代码区别于程序数据的一个重要属性是在运行时它是不能被修改的。
(2)当程序正在执行时,CPU只从存储器中读出它的指令。CPU决不会重写或修改这些指令。
3.局部性小结
- 重复引用同一个变量的程序有良好的时间局部性。
- 对于具有步长为k的引用模式的程序,步长越小,空间局部性越好。具有步长为1的引用模式的程序有很好的空间局部性。在存储器中以大步长跳来跳去的程序空间局部性会很差。
- 对于取指令来说,循环有好的空间和时间局部性。循环体越小,循环迭代次数越多,局部性越好。
三、存储器层次结构
存储器层次结构中的缓存
存储器层次结构的中心思想:对于每个k,位于k层的更快更小的存储设备作为位于k+1层的更大更慢的存储设备的缓存。
1.缓存命中
当程序需要第k+1层的某个数据对象d时,首先在当前存储在第k层的一个块中查找d,如果d刚好缓存在第k层中,就称为缓存命中。
2.缓存不命中
(1)即第k层中没有缓存数据对象d。
这时第k层缓存会从第k+1层缓存中取出包含d的那个块。如果第k层缓存已满,就可能会覆盖现存的一个块
覆盖一个现存的块的过程称为替换或驱逐。
3.缓存不命中的种类
(1)强制性不命中/冷不命中
即第k层的缓存是空的(称为冷缓存),对任何数据对象的访问都不会命中。
(2)冲突不命中
由于一个放置策略:将第k+1层的某个块限制放置在第k层块的一个小的子集中,这就会导致缓存没有满,但是那个对应的块满了,就会不命中。
(3)容量不命中
当工作集的大小超过缓存的大小时,缓存会经历容量不命中,就是说缓存太小了,不能处理这个工作集。
4.缓存管理
某种形式的逻辑必须管理缓存,而管理缓存的逻辑可以是硬件、软件,或者两者的集合。
四、高速缓存存储器
1.通用的高速缓存存储器结构
(1)高速缓存是一个高速缓存组的数组(S,E,B,m)
S:这个数组中有S=2^s个高速缓存组
E:每个组包含E个高速缓存行
B:每个行是由一个B=2^b字节的数据块组成的
m:每个存储器地址有m位,形成M=2^m个不同的地址
(2)标记位和有效位
- a有效位:每个行有一个有效位,指明这个行是否包含有意义的信息
- 标记位:t=m-(b+s)个,唯一的标识存储在这个高速缓存行中的块
- 组索引位:s
- 偏移位:b
参考资料:本人之前的每一章的博客。
《深入理解计算机系统》
(六)总结
以上的内容都是我自己在学习过程中学得很吃力但又觉得很重要的内容。通过八周的学习,对《深入理解计算机系统》这本书总算是有了初步的了解,当初刚看到这本书这么厚,简直不知道该怎么学这么厚的一本书,同时还没适应娄老师的教学模式,学习起来既费时质量也低,始终感觉跟不上进度。就这个状态的学习了八周后,总算是渐渐地感觉到了收获,状态也在渐渐改变。当然学习方法最重要,在这方面我还需努力。