期中总结

一、Linux命令

1、man

查看帮助文档:man+关键词

这里可以在中间加上数字,表示:

1是普通的Linux命令 2是系统调用,操作系统提供的服务接口 3是库函数,C语言中的函数

man -k 搜索引擎

结合grep和管道,实现多关键字查找:

man -k key1 | grep key2 | grep key3...

2、cheat

相当于小抄,man帮助还不会用,能够方便的告诉你你想要的内容。

3、grep

grep -nr 这条语句可以用来查找关键字,全文搜索,并且可以直接查找文件内的内容。

例:查找宏:

grep -nr XXX /usr/include

n:为显示行号

r:为递归查找

二、Linux工具

1、vim

三种常用模式及其转换:

普通→插入: i/a 

普通→命令行: “:”

插入/命令行→普通: Esc 或 Ctrl + [

常用操作:

退出编辑器

:w     将缓冲区写入文件,即保存修改
:wq     保存修改并退出
:x     保存修改并退出
:q     退出,如果对缓冲区进行过修改,则会提示
:q!     强制退出,放弃修改

复制粘贴
dd     删除光标所在行
dw     删除一个字(word)
x     删除当前字符
X     删除前一个字符
D     删除到行末
yy     复制一行,此命令前可跟数字,标识复制多行,如6yy,表示从当前行开始复制6行
yw     复制一个字
y$     复制到行末
p     粘贴粘贴板的内容到当前行的下面
P     粘贴粘贴板的内容到当前行的上面

2、gcc

gcc流程:

1、gcc会调用预处理程序cpp,由它负责展开在源程序中定义的宏

预处理:gcc –E hello.c –o hello.i;gcc –E调用cpp

2、编译:翻译成汇编文件

编 译:gcc –S hello.i –o hello.s;gcc –S调用ccl

3、将hello.i编译为目标代码(二进制代码)

汇 编:gcc –c hello.s –o hello.o;gcc -c 调用as

4、gcc连接器将目标文件链接为一个可执行文件

链 接:gcc hello.o –o hello ;gcc -o 调用ld

3、gdb

编译时必须加上参数-g ,例:g++ -g temp.cpp -o temp.通过Gcc编译生成可执行文件才能用Gdb进行调试。

(1)查看文件

在Gdb中键入”l”(list)就可以查看所载入的文件

(2)设置断点

只需在”b”后加入对应的行号即可(这是最常用的方式,另外还有其他方式设置断点)。如下所示:

(gdb)b 6

代码运行到第五行之前暂停(并没有运行第五行)。

(3)查看断点情况

(Gdb) info b

(4)运行代码

Gdb默认从首行开始运行代码,可键入”r”(run)即可(若想从程序中指定行开始运行,可在r后面加上行号)。

(5)查看变量值

查看断点处的相关变量值。在Gdb中只需键入”p”+变量值即可,如下所示:

(Gdb) p n

Gdb在显示变量值时都会在对应值之前加上”$N”标记,它是当前变量值的引用标记,所以以后若想再次引用此变量就可以直接写作”$N”,而无需写冗长的变量名。

(6)单步运行

使用命令”n”(next)或”s”(step),它们之间的区别在于:若有函数调用的时候,”s”会进入该函数而”n”不会进入该函数。因此,”s”就类似于VC等工具中的”step in”,”n”类似与VC等工具中的”step over”。

(7)恢复程序运行

使用命令”c”(continue).

四种断点:

1.行断点   b [行数或函数名] <条件表达式>

2.函数断点 b [函数名] <条件表达式>

3.条件断点 b [行数或函数名] <if表达式>

4.临时断点 tbreak [行数或函数名] <条件表达式>

4、makefile

make工具根据makefile文件中描述的源程序至今的相互关系来完成自动编译、维护多个源文件工程。

makefile按某种语法进行编写,需要说明如何编译各个源文件并链接生成可执行文件,要求定义源文件之间的依赖关系。
Makefile的一般写法:

test(目标文件): prog.o code.o(依赖文件列表)tab(至少一个tab的位置) gcc prog.o code.o -o test(命令)

5、静态库与动态库

静态库:

静态链接库的生成: ar rcsv libxxx.a xxx.o

静态库的使用: gcc -o main main.c -L. -lxxx   

动态库:

动态库的生成:  gcc -fPIC -c xxx.c

     gcc -shared -o libxxx.so xxx.o

动态库的使用: gcc -o main main.c -L. -lxxx

三、知识点集锦

CH01 填空:抽象是CS中一个重要的概念,在出来器里,指令集结构提供了对实际处理器的抽象。

CH01填空:计算机系统中的所有信息都是位串表示的,所谓信息就是位+上下文。
CH01填空:存储器层次结构的主要思想是上层存储器作为下层存储器的高速缓存。
CH01填空:操作系统中最基本的四个抽象是虚拟机、进程、虚拟存储器、文件。
CH07填空:链接器的两个主要任务是符号解析和重定位。
CH07 填空:加载器将可执行文件的内容映射到存储器,并运行这个程序。

CH03 填空:从i386开始,x86体系结构扩展到了32位,增加了平坦寻址模式
CH03 填空:在64位机器上,要用gcc编译出32位机器码,需要使用-m32 选项
CH03 填空:对于机器级编程来说,两种重要的抽象是ISA,虚拟地址

CH03 填空:Linux中,对目标代码code.o进行反汇编的命令是objdump -d code.o
CH03 填空:IA32指令中,操作数的三种类型是立即数、寄存器、存储器

CH03 填空:C语言中的条件表达式在汇编中是结合有条件跳转和无条件跳转实现的。
CH03 填空:C语言中的循环结构可以用条件测试和跳转组合起来实现。

CH04 判断:Y86中,状态码INS表示遇到非法指令。
CH04 填空:创建Y86代码唯一的工具是汇编器 or YAS

CH04 填空:实现一个数字系统需要三组成部分组合逻辑、存储器元素、时钟信号。
CH04 填空:HCL代表Hardware Control Language, 硬件控制语言

CH04 填空:Y86中,使用时钟寄存器保存程序计数器PC、条件代码CC和程序状态Stat 
CH04 填空:Y86中,指令执行分为六个阶段取指、译码、执行、访存、写回、更新PC 

CH06 填空:根据携带信号不同,总线可分为数据总线、地址总线、控制总线三种。
CH06 判断:程序中的循环语句具有良好的时间局部性和空间局部性。
CH06 填空:存储层次结构的中心思想是上层作为下层的缓存。
CH06 填空:缓存不命时,决定哪个块是牺牲块由替换策略来控制。
CH06 填空:空缓存的不命中叫强制性不命中或冷不命中

四、薄弱章节

3.7 过程

过程调用:

进入,为过程的局部变量分配空间将数据(以过程参数和返回值的形式)和控制从代码的一部分传递到另一部分。退出,释放这些空间。

一、栈帧结构

栈用来传递参数、存储返回信息、保存寄存器,以及本地存储。

1.栈帧

为单个过程分配的那部分栈称为栈帧,通用结构见149页

所以本质上栈帧还是栈。

2.两个指针

最顶端的栈帧以两个指针界定:

寄存器%ebp-帧指针
寄存器%esp-栈指针

栈指针可移动,所以信息访问多相对于帧指针。

3.调用的过程

课本150页过程P调用过程Q的示例。

调用者的帧应该在被调用者的下面,并且调用者返回地址是它的栈帧末尾,这样可以保证被调用者执行完毕全都出栈后,程序能够继续向下执行。

关于被调用者Q用栈的几个用处:

1.保存不能存放在寄存器中的局部变量。

当要对一个局部变量使用地址操作符&的时候,就必须要为它生成一个地址,所以要入栈。这个用法!以前没见过!

2.存放它调用的其他过程的参数。

二、转移控制

这里用到的主要就是CALL和RET这一对指令。

1.call

call指令和转移指令相似,同样分直接和间接,直接调用的目标是标号,间接调用的目标是*后面跟一个操作数指示符,和JMP一样。

CALL指令的效果是将返回地址入栈,并跳转到被调用过程的起始处。返回地址是还在程序中紧跟在call后面的那条指令的地址。

然后就会用到ret了。

2.ret

ret指从栈中弹出地址,并跳转到这个位置。

在上学期的汇编语言学习中,call和ret常被用来进行子函数、子模块的调用。

3.leave

这个指令可以使栈做好返回的准备,等价于:

movl %ebp,%esppopl %ebp

说到这里,这本书里的汇编语言很多与上学期学的8086有些许的区别,毕竟一直在不断的升级,但原理还是通用的。

三、寄存器使用惯例

程序寄存器组是唯一能被所有过程共享的资源。

这个惯例是为了防止一个过程P调用另一个过程Q时寄存器中的值被覆盖。惯例如下:

%eax,%edx,%ecx  调用者保存寄存器(Q可覆盖,P的数据不会被破坏)%ebx,%esi,%edi  被调用者保存寄存器(Q在覆盖这些值前必须压入栈并在返回前回复他们)%ebp,%esp   惯例保持%eax用来保存返回值

也就是说,当我们想嗷保存一个值以待以后运算可用的时候,有两种选择:

1.由调用者保存。在调用之前就压进栈。

2.由被调用者保存,在刚被调用的时候就压进栈,并在返回之前恢复。

你可能感兴趣的:(期中总结)