转眼已经到了期中复习,听弟弟妹妹们说他们要期中考试了,我们大三上学期的课程也已经过半。考试试题,发现问题及时沟通,首先看一下每周检测解析: 这个是比较重要的内容,也是复习和巩固所学知识点的好帮手,下面是老师给出的解析链接。
https://group.cnblogs.com/topic/75467.html
一教材内容:
ch01:计算机系统漫游
1、信息=位+上下文
系统中所有信息的都是由一串位表示的,区分不同数据对象的唯一方法是它的上下文。
2、存储系统核心思想———缓存
3、操作系统核心抽象:文件、虚存、进程、虚拟机
4、查看源文件用od 命令 : od -tc -tx1 hello.c
ch02:信息的表示和处理
1、三种数字:无符号数、有符号数(2进制补码)、浮点数
进制转换:拿二进制作中间结果
2、信息存储
gcc -m32 可以在64位机上(比如实验楼的环境)生成32位的代码
字节顺序:是网络编程的基础
两种字节顺序:
小端是“高对高、低对低”
大端是“高对低、低对高”
区别:逻辑运算(结果是1或0)和位运算(结果是位向量)
只要一个与非门,就可以完成所有的逻辑运算。
掩码是位运算的重要应用,对特定位可以置一,可以清零
3、整数表示与运算
C语言中有符号数和无符号数的转换规则,位向量不变——信息就是位+上下文。
0扩展和符号扩展:
零扩展:要将一个无符号数转换为一个更大的数据类型,只需简单的最高位前加0。
符号扩展:将一个补码数字转换为一个更大的数据类型,在表示中添加最高有效位值的副本。
截断数字:截断一个数字可能会改变其值,这也是值溢出的一种形式。
计算机执行的“整数运算”实际上是一种模运算。
表示数字的有限字长限制了可能的值的取值范围。
无论运算数是以无符号形式还是补码形式表示,都有完全一样或者非常类似的位级行为。
4、浮点数——IEEE浮点表示
IEEE浮点标准用V = (-1)^s × M × 2^E的形式来表示一个数
三个参数:
符号:s决定这个数是负数(s=1)还是正数(s=0),而对于数值0的符号位解释作为特殊情况处理。
尾数:M是一个二进制小数,它的范围是1~2-ε,或者是0~1-。
阶码:E的作用是对浮点数加权,这个权重是2的E次幂(可能是负数)。
将浮点数的位表示划分为三个字段,分别对这些值进行编码:
一个单独的符号位s直接编码符号s。
k位的阶码字段exp = ek-1…e1e0编码阶码E。
n位小数字段frac = fn-1…f1 f0编码尾数M,但是编码出来的值也依赖于阶码字段的值是否等于0。
5、补码:是利用寄存器的长度是固定的特性简化数学运算,只要一个加法器就可以实现所有的数学运算。
ch03:程序的机器级表示
1、ISA指令集体系结构
机器级程序的格式和行为,它定义了处理器状态、指令的格式以及每条指令对状态的影响。
程序计数器(通常称为PC,用%eip表示),指示将要执行的下一条指令在存储器中的地址。
整数寄存器文件:存储地(对应于C语言的指针)或整数数据。
条件码寄存器:保存着最近执行的算数或逻辑指令的状态信息,用来实现控制或者数据流中的条件变化。
浮点寄存器:用来存放浮点数据。
2、用objdump -d xxx.o -o xxx.s 反汇编
3、leal,从存储器读数据到寄存器,而从存储器引用的过程实际上是将有效地址写入到目的操作数。目的操作数必须是一个寄存器。
4、栈帧
栈帧结构
为单个过程分配的栈叫做栈帧,寄存器%ebp为帧指针,而寄存器指针%esp为栈指针,程序执行时栈指针移动,大多数信息的访问都是相对于帧指针。
栈向低地址方向增长,而栈指针%esp指向栈顶元素。
转移控制
call:目标是指明被调用过程起始的指令地址,效果是将返回地址入栈,并跳转到被调用过程的起始处。
ret:从栈中弹出地址,并跳转到这个位置。
函数返回值存在%eax中
ch04:处理器体系结构
1、Y86指令集体系结构
程序员可见的状态(Y86程序中的每条指令都会读取或修改处理器状态的某些部分)
8个程序寄存器:%eax,%ecx,%edx,%ebx,%esi,%edi,%esp和%ebp。
条件码:ZF(零)、SF(符号)、OF(有符号溢出)
程序计数器(PC):存放当前正在执行的指令的地址
存储器:很大的字节数组,保存着程序和数据。Y86系统用虚拟地址来引用存储器的位置,硬件和操作系统软件联合起来将虚拟地址翻译成实际或者物理地址。
状态码(stat):表明程序执行的总体状态。(异常处理)
2、指令编码规则
高4位为代码部分,低四位为功能部分
状态码:描述程序执行的总体状态。
值 名字 含义
1 AOK 正常操作
2 HLT 处理器执行halt指令(指令停止)
3 ADR 遇到非法地址
4 INS 遇到非法指令
3、逻辑设计和硬件控制语言HCL
实现一个数字系统:
计算对位进行操作的函数的组合逻辑
存储位的存储器元素
控制存储器元素更新的时钟信号
ch06:存储器层次结构
1、三种常见存储技术:RAM/ROM/磁盘
2、随机访问存储器(RAM)
静态RAM(SRAM)
动态RAM(DRAM)
2、非易失性存储器(ROM)
可编程ROM(PROM):只能被编程一次。PROM每个存储单元有一种熔丝,只能用高电流熔断一次。
可擦写可编程ROM(EPROM):紫外线光照射过窗口,EPROM就被清除为0,被擦除和重编程的次数为1000次。
电子可擦除ROM(EEPROM):不需要一个物理上独立的编程设备,因此可以直接在印制电路卡上编程,能够编程的次数为10^5。
闪存:基于EEPROM,为大量的电子设备提供快速而持久的非易失性存储。
3、磁盘
磁盘结构:盘片、磁道、扇区、间隙、柱面
磁盘容量:记录密度、磁道密度、面密度
访问时间:寻道时间+旋转时间+传送时间
访问磁盘:CPU使用一种称为存储器映射I/O的技术向I/O设备发出命令,地址空间中为I/O设备通信保留的地址称为I/O端口。
4、数据总线、控制总线、地址总线
系统总线、存储总线、I/O总线
5、读写事务:
读事务,从主存传数据到CPU;
写事务,从CPU传数据到主存。
6、局部性原理:一个编写良好的计算机程序倾向于引用邻近于其他最近引用过的数据项,或者最近引用过的数据项本身。有良好局部性的程序比局部性差的程序运行的更快,在硬件层引入高速缓存存储器就体现了局部性原理。
7、对程序数据引用的局部性
时间局部性(temporal locality):被引用过一次的存储器位置在未来会被多次引用(通常在循环中)。
空间局部性(spatial locality):如果一个存储器的位置被引用,那么将来他附近的位置也会被引用。
9、取指令的局部性
程序指令是存放在存储器中的,CPU读取这些指令的过程中评价一个程序关于取指令的局部性。
代码区别与程序数据的一个重要属性就是在运行时指令是不能被修改的。
10、良好的局部性程序:
重复引用同一个变量的程序有良好的时间局部性
对于具有步长为k的引用模式的程序,步长越小,空间局部性越好。
对于取指令来说,循环具有良好的时间和空间局部性。循环体越小,迭代次数越多局部性越好。
11、存储器层次结构中心思想:每层存储设备都是下一层的“缓存”
12、缓存命中:当程序需要第k+1层的某个数据对象d时,首先在当前存储的第k层的一个块中查找d,如果d刚好在第k层中,则称为缓存命中。命中率:1-不命中率
缓存不命中:如果k层中没有缓存数据d,则称为缓存不命中,此时要从k+1层取出包含d的块,可能会覆盖(替换/驱逐)现在的一个块(牺牲块)。决定该替换哪个快是缓存的替换策略来控制的。不命中率:不命中数量/引用数量
13、缓存不命中的种类
强制性不命中/冷不命中:第k层缓存是空的(冷缓存),只是短暂的状态,不会在反复访问存储器使得缓存暖身之后的稳定状态出现。
冲突不命中:第k+1层的第i块,必须放置在第k层的块(i mod 4)中,这种限制性的放置策略引起冲突不命中。
14、高速缓存存储器结构
高速缓存的结构用元组(S,E,B,m)来描述,高速缓存的大小C = S * E * B
s个组索引位:一个无符号整数,说明字必须存储在哪个组中。
t个标记位:组中的哪一行包含这个字。
b个块偏移位:在B个字节的数据块中的字偏移。
ch07:链接
1、链接器的两个任务
符号解析
重定位
2、目标文件的三种形式
可重定位目标文件
可执行目标文件
共享目标文件
3、目标文件格式
a.out 可执行文件
COFF 一般目标文件格式
PE 可移植可执行文件格式
ELF 可执行可连接文件格式
4、readelf命令:用于显示一个/多个elf格式目标文件的信息
5、全局符号
强符号:函数和已经初始化的全局变量
弱符号:未初始化的全局变量
规则:
不允许有多个强符号
若有一个强符号和多个弱符号,选强符号
若有多个弱符号,任选一个
6、处理目标文件的工具
AR 创建静态库,插入、删除、列出和提取成员
STRINGS 列出一个目标文件中所有可打印的字符串
STRIP 从目标文件中删除符号表中定义的符号
NM 列出一个目标文件中节的名字和大小
READELF 显示一个目标文件的完整结构
OBJDUMP 二进制工具之母,可以显示一个目标文件中所有的信息
二:常用的Linux命令
man命令
man命令是Linux下的帮助指令,通过man指令可以查看Linux中的指令帮助、配置文件帮助和编程帮助等信息。
常用选项:
-a:在所有的man帮助手册中搜索
-k:根据关键字搜索联机帮助,是一种模糊搜索
-f:关键字精确搜索,等价于whatis指令,显示给定关键字的简短描述信息
-M:指定man手册搜索的路径
参数:
数字:指定从哪本man手册中搜索帮助
关键字:指定要搜索帮助的关键字
man -k:常用来搜索,结合管道使用。例句如下:man -k k1 | grep k2 | grep 2
cheat命令
在linux上,虽然我们可以用man命令调出该指令的命令帮助列表,但是其实我们不一定会看,因为那帮助太繁琐枯燥了,内容又长,我们又不知道自己要用的命令的例子又是怎样,所有有了简单易懂的cheat命令。正如它的名字一样,就像作弊一样,我们可以跳过学习的阶段,直接掌握如何使用一个命令。
grep命令
grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。
命令格式:grep [options]
主要参数:
-c:只输出匹配行的计数
-I:不区分大小写(只适用于单字符)
-h:查询多文件时不显示文件名
-l:查询多文件时只输出包含匹配字符的文件名
-n:显示匹配行及行号
-s:不显示不存在或无匹配文本的错误信息
-v:显示不包含匹配文本的所有行
find命令
find命令用来在指定目录下查找文件。任何位于参数之前的字符串都将被视为欲查找的目录名。如果使用该命令时,不设置任何参数,则find命令将在当前目录下查找子目录与文件。并且将查找到的子目录和文件全部进行显示。
命令格式:find pathname -options [-print -exec -ok ...]
参数:
pathname:find命令所查找的目录路径。例如用.来表示当前目录,用/来表示系统根目录
print:find命令将匹配的文件输出到标准输出
常用选项:
-name:按照文件名查找文件
-perm:按照文件权限来查找文件
mtime -n +n:按照文件的更改时间来查找文件, - n表示文件更改时间距现在n天以内,+ n表示文件更改时间距现在n天以前
-newer file1 ! file2:查找更改时间比文件file1新但比文件file2旧的文件
-type:查找某一类型的文件,诸如:b - 块设备文件,d - 目录,c - 字符设备文件,p - 管道文件,l - 符号链接文件,f - 普通文件
-size n:[c] 查找文件长度为n块的文件,带有c时表示文件长度以字节计
-depth:在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找
举例:查找当前目录下大小大于50M的文件,查找大小大于10K的文件
locate命令
locate命令其实是find -name的另一种写法,但是要比后者快得多,原因在于它不搜索具体目录,而是搜索一个数据库(/var/lib/locatedb),这个数据库中含有本地所有文件信息。Linux系统自动创建这个数据库,并且每天自动更新一次,所以使用locate命令查不到最新变动过的文件。为了避免这种情况,可以在使用locate之前,先使用updatedb命令,手动更新数据库。
命令格式:locate [选择参数] [样式]
命令参数:
-e:将排除在寻找的范围之外
-1:如果是1则启动安全模式,在安全模式下,使用者不会看到权限无法看到的档案。这会使速度减慢,因为 locate必须至实际的档案系统中取得档案的权限资料
-f:将特定的档案系统排除在外,例如我们没有到必要把proc档案系统中的档案放在资料库中
-q:安静模式,不会显示任何错误讯息
-n:至多显示 n个输出
-r:使用正规运算式 做寻找的条件
-o:指定资料库存的名称
-d:指定资料库的路径
-h:显示辅助讯息
-V:显示程式的版本讯息
whereis命令
whereis命令是定位可执行文件、源代码文件、帮助文件在文件系统中的位置。这些文件的属性应属于原始代码,二进制文件,或是帮助文件。whereis程序还具有搜索源代码、指定备用搜索路径和搜索不寻常项的能力。whereis命令只能用于程序名的搜索,而且只搜索二进制文件(参数-b)、man说明文件(参数-m)和源代码文件(参数-s)。如果省略参数,则返回所有信息。
命令格式:whereis [-bmsu] [BMS 目录名 -f ] 文件名
主要参数:
-b:定位可执行文件
-m:定位帮助文件
-s:定位源代码文件
-u:搜索默认路径下除可执行文件、源代码文件、帮助文件以外的其它文件
-B:指定搜索可执行文件的路径
-M:指定搜索帮助文件的路径
-S:指定搜索源代码文件的路径
which命令
which指令会在PATH变量指定的路径中,搜索某个系统命令的位置,并且返回第一个搜索结果。which是根据使用者所配置的PATH变量内的目录去搜寻可运行档的,所以,不同的PATH配置内容所找到的命令是不一样的。
命令格式:which 可执行文件名称
命令参数:
-n:指定文件名长度,指定的长度必须大于或等于所有文件中最长的文件名
-p:与-n参数相同,但此处的包括了文件的路径
-w:指定输出时栏位的宽度
-V:显示版本信息
find、locate、which、whereis的区别
which (寻找执行档) :这个指令是根据PATH这个环境变量所规范的路径,去搜寻执行档的档名,所以,重点是找出执行档而已,which 后面接的是完整档名
whereis (寻找特定档案):搜寻linux数据库档案中所记录的东西,和locate的主要区别在于后面的参数
locate:搜寻linux数据库档案中所记录的东西,后面直接跟档案的部分名称就行
find:直接搜索整个硬盘
sort命令
将文本文件内容加以排序。可针对文本文件的内容,以行为单位来排序。
参数:
m:将几个排序好的文件进行合并。
n:依照数值的大小排序
Linux Bash中,ls . | sort 命令的功能是(显示当前目录内容并排序)
du命令
显示目录或文件的大小。du会显示指定的目录或文件所占用的磁盘空间。
参数:
a:显示目录中个别文件的大小。
b:显示目录或文件大小时,以byte为单位。
c: 除了显示个别目录或文件的大小外,同时也显示所有目录或文件的总和
ls命令
显示指定工作目录下之内容(列出目前工作目录所含之档案及子目录)。
参数:
a:显示所有档案及目录
A:同 -a ,但不列出 "." (目前目录) 及 ".." (父目录)
t:将档案依建立时间之先后次序列出
列出目前工作目录下所有档案及目录;目录于名称后加 "/", 可执行档于名称后加 "*" : ls -AF
Linux Bash中,把ls命令显示当前目录的结果存入ls.txt的命令输出重定向命令是(ls > ls.txt)
vi、 gcc、gdb、make的使用
Vim六种模式
普通模式(Normal mode):在普通模式中,用的编辑器命令,比如移动光标,删除文本等等。这也是Vim启动后的默认模式。在普通模式中,进入插入模式比较普通的方式是按a(append/追加)键或者i(insert/插入)键。
插入模式(Insert mode):在插入模式中,可以按ESC键回到普通模式。
可视模式(Visual mode):命令多与字母v有关,移动命令会扩大高亮的文本区域。高亮区域可以是字符、行或者是一块文本。
选择模式(Select mode):这个模式中,可以用鼠标或者光标键高亮选择文本,不过输入任何字符的话,Vim会用这个字符替换选择的高亮文本块,并且自动进入插入模式。
命令行模式(Command line mode):在命令行模式中,执行命令(:键),搜索(/和?键)或者过滤命令(!键)。在命令执行之后,Vim返回到命令行模式之前的模式,通常是普通模式。
Ex模式(Ex mode):这和命令行模式比较相似,在使用:visual命令离开Ex模式前,可以一次执行多条命令。
Vim常用命令总结
插入:
i:在当前光标处进行编辑
a:在光标后插入编辑
退出:
q!:强制退出,不保存
:q:退出
:wq!:强制保存并退出
:wq:保存并退出
:w <文件路径>:另存为
删除:
x:删除游标所在的字符
dd:删除整行
GCC编译过程
以hello.c为例
预处理:gcc –E hello.c –o hello.i ;gcc –E调用cpp 产生预处理过的C原始程序
编译: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 产生可执行文件
运行: ./hello
GDB调试
进入gdb:
gcc -g xxx.c -o xxx
gdb xxx
查看源码:
(gdb) l:进行行号提示
(gdb) b n:在第n行设置断点
(gdb) r:运行代码,运行至断点处
(gdb) n:单步运行
(gdb) c:使程序继续往下运行,直到再次遇到断点或程序结束
(gdb) q:退出GDB
(gdb) watch n:在"n"设置了观察点,观察变量的变化情况
makefile
功能:识别文件代码是否更新,减少编译工作量
格式:
目标体:依赖文件
目标体:由make创建,通常是目标文件或可执行文件
依赖文件:创建目标体所依赖的文件
运行命令:创建每个目标体时需要的运行命令,必须以tab键开头。
使用make的格式:make 目标体