期中总结
重要知识点
Linux常用命令
-
man:man 命令或参数名称,即可查看linux帮助手册中关于该命令或者参数的描述。
man –k k1 | grep k2 | grep 2 关键字检索,k1,k2位关键字,为系统级调用。
-
cheat:cheat是在GNU通用公共许可证下,为Linux命令行用户发行的交互式备忘单应用程序。它提供显示Linux命令使用案例,包括该命令所有的选项和简短但尚可理解的功能。
-
grep:查找文件里符合条件的字符串。
grep –nr xxx /usr/include:查看C语言中xxx语句的注释。
-
find:查找文件或目录。
-
locate:查找文件位置。
-
whereis:查找文件。
-
which:查找文件。
-
apt-get:安装软件或更新。
-
groups:查找当前登录用户所属的用户组。
-
chmod:修改文件的权限。
-
rm:删除文件。
-
cat:查看文件。
VIM的基本命令
移动光标:h左,j下,k上,l右。
进入VIM:vim 文件名<回车>。
退出VIM:退出不保存:q!<回车>。
保存后退出:wq<回车>。
正常模式下删除光标所在位置的字符,请按∶ x。
正常模式下要在光标所在位置开始插入或附加文本,请按∶
i 输入插入文本 <ESC> 在光标之前插入。
A 输入附加文本 <ESC> 在光标之后附加。
正常模式下删除指令:d。
输入 u 来撤消最后执行的命令,输入 U 来修正整行。
输入 CTRL-R撤消掉撤消命令。
启动帮助系统:正常模式下输入:help<回车>。
GCC命令
用gcc命令编译运行C语言文件
(1) 预处理阶段:将*.c文件转化为*.i预处理过的C程序。
(2) 编译阶段:将*.i文件编译为汇编代码*.s文件。
(3) 汇编阶段:将*.s文件转化为*.o的二进制目标代码文件。
(4) 链接阶段:将*.o文件转化为可执行文件。
(5) 生成可执行文件:将*.o转换为可执行文件。
(6) 执行可执行C语言文件。
gcc常用选项列表
-c 只编译不链接,生成目标文件".o"
-S 只编译不汇编,生成编码代码
-E 只进行预编译,不做其他处理
-g 在可执行程序中包含标准调试信息
-o file 将file文件指定为输出文件
-v 打印出编译器内部编译各过程的命令行信息和编译器的版本
-I dir 在头文件的搜索路径中添加dir目录
GBD调试器
gdb调试器是一款GNU开发组织发布的UNIX/Linux下的调试工具。
使用流程
先用gcc对test.c进行编译,注意一定要加上选项"-g",这样编译出的可执行代码中才包含调试信息,否则之后gdb无法载入该可执行文件。
GDB常用命令:
• b 设断点(要会设4种断点:行断点、函数断点、条件断点、临时断点)
• run 开始运行程序
• bt 打印函数调用堆栈
• p 查看变量值
• c 从当前断点继续运行到下一个断点
• n 单步运行
• s 单步运行
• quit 退出GDB
Make工程管理器
makefile是make读入的唯一配置文件
在一个makefile中通常包含如下内容:
i. 需要由make工具创建的目标体(target),通常是目标文件或可执行文件。
ii. 要创建的目标体所依赖的文件(dependency_file);
iii. 创建每个目标体时需要运行的命令(command),这一行必须以制表符(Tab键)开头。
格式:
target: dependency_files
command
例:
第一章
-
计算机系统中的所有信息都是位串表示的,就是位+上下文。
-
存储器层次结构的主要思想是上层存储器作为下层存储器的高速缓存。
-
操作系统的最基本的四个抽象是虚拟机、进程、虚拟存储器、文件。
-
指令集结构提供了实际处理器的抽象。
-
并行的三个层次:线层级并发,指令集并发,SIMD。
第二章
-
三种数字表示:无符号,补码,浮点数。
-
寻址和字节顺序:
-
小端法:在存储器中按照从最低有效字节到最高有效字节的顺序存储对象,"高对高,低对低"。
-
大端法:在存储器中按照从最高有效字节到最低有效字节的顺序存储。"高对低,低对高"。
-
-
掩码:我们能通过指定一个位向量掩码,有选择地使能或是不能屏蔽一些信号,其中某一位位置上为1时,表明信号i是有效的,而0表明该信号是屏蔽的。因此,这个掩码表示的就是设置为有效信号的集合。掩码运算通常是通过位级运算来实现的。
-
C语言中无符号和有符号的转换:位向量不变,只是上下文的读取方式不同,所以根据不同的读取规则,最终的读取结果也不同。这就是所谓的信息就是位+上下文。注:c语言中要创建一个无符号常量,必须加上后缀字符'U'或者'u'。转换的原则是底层的位表示保持不变。
-
零扩展:将一个无符号数转换为一个更大的数据类型,我们只需要简单地在开头添加0。
-
符号扩展:将一个补码数字转换为一个更大的数据类型,规则是在表示中添加最高有效位的值的副本。
-
整数溢出:指完整的整数结果不能放到数据类型限制的字长中去。
避免整数溢出:当两个整数进行运算时,其结果用更大的数据类型进行存储。比如两个int类型的整数相乘的结果用long long数据类型的变量来存储。
-
IEEE浮点标准,float和double类型p70。
-
整数与浮点数转换规则
当在int、float和double格式之间进行强制类型转换时,程序改变数值和位模式的原则如下(假设int是32位的):
1. 从int转换成float,数字不会溢出,但是可能被舍入。
2. 从int或float转换成double,因为double有更大的范围(也就是可表示值的范围),也有更高的精度(也就是有效位数),所以能够保留精确的数值。
3. 从double转换成float,因为范围要小一些,所以值可能溢出为+∞或-∞。另外由于精确度较小,它还可能被舍入。
4. 从float或者double转换为int,值将会向零舍入。
第三章
-
对于机械级编程来说,两种重要的抽象是ISA和虚拟地址。
-
X86的三代寻址方式:
-
DOS时代的平坦模式,不区分用户空间和内核空间,很不安全。
-
8086的分段模式。
-
IA32的带保护模式的平坦模式。
-
-
gcc中反汇编:objdump –d xxx.o。
-
查看二进制文件:用od命令查看,也可以用gdb的x命令查看。
-
汇编ATT格式和Intel格式的区别:
-
Intel代码省略了指示大小的后缀。我们看到指令mov,而不是movl。
-
Intel代码省略了寄存器名字前面的'%'符号。用esp,而不是%esp。
-
Intel代码用不同的方式来描述存储器中位置。例如,是'DWORD PTR [ebp+8]'而不是'(ebp)'。
-
-
不同数据汇编代码的后缀
汇编代码指令都有一个字符后缀,表明操作数大小。
-
后缀b代表大小为字节。例如:movb(传送字节)。
-
后缀w代表大小为字。例如:movw(传送字)。
-
后缀l代表大小为双字。例如:movl(传送双字)。
-
-
三种操作数类型:立即数,寄存器,存储器。
-
汇编的寻址方式:立即数寻址、寄存器寻址、绝对寻址、间接寻址、(基址+偏移量)寻址、变址寻址、比例变址寻址。
-
数据传送指令:MOV:传送字节,MOVS:传送符号扩展的字节,MOVZ:传送零扩展的字节。
-
条件码:CF:进位标志、ZF:零标志、SF:符号标志、OF:溢出标志。
-
其他指令详见课本。
-
过程与栈:一个过程调用包括将数据(以过程参数和返回值的形式)和控制从代码的一部分传递到另一部分。另外,它还必须在进入时为过程的局部变量分配空间,并在退出时释放这些空间。数据传递、局部变量的分配和释放都是通过操纵程序栈来实现的。机器用栈来传递过程参数、存储返回信息、保存寄存器用于以后恢复,以及本地存储。为单个过程分配的那部分栈称为栈帧。
-
关于栈帧的GDB命令:bt(backtrace)列出调用栈、frame(f)选择栈帧、up和down:可以在栈的各层之间跳转。
-
C语言中的条件表达式在汇编中是结合有条件跳转和无条件跳转语句实现的。
-
C语言中的循环结构可以用条件测试和跳转组合起来实现的。
-
栈用来传递参数、存储返回信息、保存寄存器、本地存储。
-
Linux汇编中,形成空调用栈帧的语句是
-
push %ebp movl %esp %ebp
-
-
Linux汇编中,函数有返回值存在%eax寄存器中。
第四章
-
指令集体系结构:一个处理器支持的指令和指令的字节级编码为它的指令集体系结构。
-
实现数字系统需要三个组成部分:组合逻辑、存储器元素、时钟信号。
-
创建Y86代码唯一的工具是汇编器or YAS。
-
HCL代表Hardware Control Language,硬件控制语言。
-
Y86中,时钟寄存器保存计数器PC、条件代码CC和程序状态Stat。
-
Y86中,指令执行分为六个阶段:取指、译码、执行、访存、写回、更新PC。
-
Y86处理器状态类似于IA32。有8个程序寄存器:%eax,%ecx,%edx,%ebx,%esi,%edi,%esp和%ebp。处理器每个程序寄存器存储一个字。寄存器%esp被入栈、出栈、调用和返回指令作为栈指针。在其他情况中,寄存器没有固定的含义或固定值。有3个一位的条件码:ZF、SF和OF,它们保存最近的算术或逻辑指令所造成影响的相关信息。程序计数器(PC)存放当前正在执行的指令地址。
第六章
-
三种常见的存储技术:RAM、ROM、磁盘。
-
RAM(随机访问存储器)分类:静态RAM(SRAM)和动态RAM(DRAM)。
-
两类RAM区别:静态RAM比动态RAM更快,但也贵得多且功耗更大。
-
ROM(非易失性存储器)分类:PROM、EPROM、EEPROM、FLASH。
-
读事物:从主存传送数据到CPU。
-
写事物:从CPU传送事物到主存。
-
磁盘:磁盘由盘片构成的。每个盘片有两面或者称为表面,表面覆盖着磁性记录材料。盘片中央有一个可以旋转的主轴,它使得盘片以固定的旋转速率旋转,通常是5400~15000转每分钟。
-
对扇区的访问时间有主要的三个部分:寻道时间、旋转时间、传送时间。
-
根据携带信号不同,总线可分为数据总线、地址总线、控制总线三种。
-
逻辑磁盘块的逻辑块号可以翻译成一个盘面、磁道、扇区三元组。
-
CPU使用存储器映射I/O技术向I/O设备发出命令。
-
局部性有两种形式时间局部性、空间局部性。
-
存储层次结构的中心思想是上层作为下层的缓存。
-
缓存不命时,决定哪个块是牺牲块由替换策略来控制。
-
空缓存的不命中叫强制性不命中或冷不命中。
-
容量不命中的原因是缓存太小。
-
高速缓存结构可以用元组(S,E,B,m)来描述。
第七章
-
链接器的两个主要任务:符号解析和重定位。
-
加载器将可执行文件的内容映射到存储器,并运行这个程序。
-
每个可重定位目标模块m都有一个符号表,它包含m所定义和引用的符号信息。在链接器的上下文中,有三种不同的符号:
-
全局符号:由m定义并能被其他模块引用的符号。全局链接器符号对应于非静态的C函数以及被定义为不带C static属性的全局变量。
-
外部符号:由其他模块定义并被模块m引用的全局符号。对应于定义在其他模块中的C函数和变量。
-
本地符号:只被模块m定义和引用的符号。
-
函数和初始化的全局变量是强符号,未初始化的全局变量是弱符号。
-
处理目标文件的工具:
-
AR:创建静态库,插入、删除、列出和提取成员列表。
-
STRINGS:列出一个目标文件中所有课打印的字符串。
-
STRIP:从目标文件中删除符号表的信息。
-
NM:列出一个目标文件的符号表中定义的符号。
-
SIZE:列出目标文件中节的名字和大小。
-
READELF:显示一个目标文件的完整结构,包括ELF头中编码的所有信息。包含SIZE和NM的功能。
-
OBJDUMP:所有二进制工具之母。能够显示一个目标文件中所有的信息。它最大的作用是反汇编.text节中的二进制指令。
-
LDD:列出一个可执行文件在运行时所需的共享库。
-
-
gcc –f PIC xxx.c中的PIC的意思是位置无关的代码。
学习收获
-
学会了linux操作系统命令行模式的基本操作。
-
学会了在linux操作系统的环境下进行C语言编程及利用gdb进行调试。
-
学会使用makefile文件管理器静态库和共享库的制作。
-
理解了在计算机系统中信息的定义以及数据的表示。
-
复习巩固了上学期汇编所学的内容。
-
初步理解了处理器的体系结构。
-
对计算机的存储结构有了进一步的理解。
自己的不足
-
对部分理论知识理解不充分。
-
部分常用指令使用不够熟练,经常需要查表。
改进措施:增加实践时间,以便和理论相互验证,加强理解,同时增加对指令的熟悉程度。
对课程的建议
1.课上加强对课下实践所用到的理论的讲解。
原因:有时候,课下所做的实践只是造着书上的代码敲,明白代码大概的作用,但是对其原理的认识却不够清晰,所以需要课上对所用到的理论进行详细讲解以便和实践相互印证,加强对所学知识的理解。
2.如果有难度较高的实践任务发布,希望能提前在截止日期之前2周以上发布。
原因:从第十周开始其他课程的实验就陆续开始了,所以希望提前足够的时间发布任务,以便有充足的时间来准备和完成实践。