标签:
熟知任务:
1. 复习Linux命令,特别是man -k, cheat, grep -nr xxx /usr/include
2. 复习vi, gcc, gdb,make的使用
3. 复习教材内容ch01 ch02 ch03 ch04 ch06 ch07
4. 复习前面的考题(答案解析见http://group.cnblogs.com/topic/73060.html) ,下次考试考每次考试错的最多的题目
5. 期中总结发一篇Blog:
知识点总结
自己的收获(不要假大空)
自己的不足(要具体,有改进措施)
课程建议和意见(要有理由)
一、Linux命令
man -k:
常用来搜索,结合管道使用。例句如下:
man -k k1 | grep k2 | grep 2
搜索同时含有k1和k2,且属于系统调用。
最后的数字意味着帮助手册中的区段,man手册共有8个区段,最常用的是123,含义如下:
1.Linux 2.系统调用 3.c语言
但是当单独用man语句的时候,想查看其中的单独某个区段内的解释时,用法是这样的:
man 3 printf
即查找c语言中printf的用法。
cheat
cheat是非常好用的“打小抄”搜索工具,能够方便的告诉你你想要的内容。
示例:
cheat vim
grep -nr
这条语句可以用来查找关键字,全文搜索,并且可以直接查找文件内的内容。其中:
n:为显示行号 r:为递归查找
例如,如果想查找某个宏,我们已知宏保存在include文件夹中,所以可以使用下列语句:
grep -nr XXX /usr/include(XXX为所要找的宏)
二、工具使用
vim
vim是一种非常好用的编辑器,总共有六种基本模式,最常用的是普通模式、插入模式和命令行模式。需要熟悉这三种模式之间的切换方式:
普通→插入: i 或 a 插入→普通: Esc 或 Ctrl + [ 普通→命令行: : 命令行→普通:Esc 或 Ctrl + [
常用的进入、保存和退出指令:
进入:
vim
文件名 保存:命令行模式 :w 退出:命令行模式 :q
常用动作:
删除:dd删除整行 复制:yy复制整行 粘贴:p
※实用功能:交换上下行——ddp,快速交换光标所在行与它下面的行。
vim的功能很强大,并且可以移植到很多种不同的程序中,但是我们现在使用的过程中真正用到的命令很少也很简单,更多的技巧参见第二周笔记。
gcc
常用选项
-c 只编译不链接,生成目标文件.o -S 只编译不汇编,生成汇编代码 -E 只进行预编译,不做其他处理 -g 在可执行程序中包含标准调试信息 -o file 将file文件指定为输出文件 -v 打印出编译器内部编译各过程的命令行信息和编译器的版本 -I dir 在头文件的搜索路径列表中添加dir目录
编译过程
预处理: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** 创建可执行目标文件
-o后面是接的你给生成的文件指定的名字,如果不指定,则默认为a.out
在命令行上运行这个可执行目标文件需要输入它的名字:
./a.out
其中./代表当前目录。
gdb
注意:使用GCC编译时要加“-g”参数,然后才能够用gdb调试
GDB最基本的命令有:
gdb programm(启动GDB) l 查看所载入的文件 b 设断点 info b 查看断点情况 run 开始运行程序 bt 打印函数调用堆栈 p 查看变量值 c 从当前断点继续运行到下一个断点 n 单步运行(不进入) s 单步运行(进入) quit 退出GDB
四种断点:
1.行断点 b [行数或函数名] <条件表达式> 2.函数断点 b [函数名] <条件表达式> 3.条件断点 b [行数或函数名] <if表达式> 4.临时断点 tbreak [行数或函数名] <条件表达式>
另外的调试工具:
cgdb,有单独的debug窗口,更方便查看
ddd,图形页面
Make和Makefile
这是实现自动化编译的好方法。
Makefile的一般写法:
一个Makefile文件主要含有一系列的规则,每条规则包含以下内容:
需要由make工具创建的目标体,通常是可执行文件和目标文件,也可以是要执行的动作,如‘clean’;
要创建的目标体所依赖的文件,通常是编译目标文件所需要的其他文件。
创建每个目标体时需要运行的命令,这一行必须以制表符TAB开头
格式为:
test(目标文件): prog.o code.o(依赖文件列表) tab(至少一个tab的位置) gcc prog.o code.o -o test(命令) ....... 即: target: dependency_files command
定义变量的两种方式:
(1)递归展开方式 VAR=var (2)简单方式 VAR:=var
使用变量的格式为: $(VAR)
知识点总结
第1章 计算机系统漫游
计算机系统是由硬件和系统软件组成的,它们共同协作以运行应用程序。计算机内部的信息被表示为一组组的位.它们依据上下文有不同的解释方式。程序被其他程序翻译成不同的形式,开始时是ASCII文本.然后被编译器和链接器翻译成二进制可执行文件。
处理器读取并解释存放在主存里的二进制指令,因为计算机可以把大量的时间用于存储器、I/O设备和CPU寄存器之间复制数据,所以将系统中的存储设备划分成层次结构--CPU寄存器在顶部,接着是多层的硬件高速缓存存储器、DRAM主存和磁盘存储器在层次模型中,位于更高层的存储设备比低层的存储设备要更快,单位比特开销也更高。层次结构中较高层次存储设备可以作为较低层次设备的高速缓存。
操作系统内核是应用程序和硬件之间的媒介。
它提供三个基本的抽象:1)文件是对I/O的抽象;2)虚拟存储器是对主存和磁盘的抽象:3)进程是对处理器、主存抽象和I/O设备的设备最后,网络提供了计算机系统之间通信的手段。从特殊系统的角度来看,网络就是一种I/O设备。
第2章 信息的表示和处理
△计算机将信息按位编码,通常组织成字节序列。用不同的编码方式表示整数、实数和字符串。不同的计算机模型在编码数字和多字节数据中的字节排序时使用不同的约定。
C语言的设计可以包容多种不同字长和数字编码的实现。虽然高端机器逐渐开始使用64位字长,但是目前大多数机器仍使用32位字长。大多数机器对整数使用补码编码,而对浮点数使用IEEE浮点编码。在位级上理解这些编码,并且理解算术运算的数学特性,对于想使编写的程序能在全部数值范围上正确运算的程序员来说,是很重要的。
在相同长度的无符号和有符号整数之间进行强制类型转换时,大多数C语言实现遵循的原则是底层的位模式不变。在补码机器上,对于一个W位的值,这种行为是由函数T2Uw和U2Tw来描述的。
第3章 程序的机器级表示
△在本章中,我们窥视了C语言提供的抽象层下面的东西,以了解机器级编程。通过让编译器产生机器级程序的汇编代码表示,我们了解了编译器和它的优化能力,以及机器、数据类型和指令集。在第5章,我们会看到,当编写能有效映射到机器上的程序时,了解编译器的特性会有所帮助。我们还更完整地了解了程序如何将数据存储在不同的存储器区域中。在第12章会看到许多这样的例子,我们需要知道个程序变量是在运行时栈中,是在某个动态分配的数据结构中,是在某个全局存储位置中。理解程序如何映射到机器上,会让理解这些存储之间的区别容易些。
机器级程序和它们的汇编代码表示,与C程序的差别很大。在汇编语言程序中,各种数据类型之间的差别很小。程序是以指令序列来表示的,每条指令都完成一个单独的操作。部分程序状态,如寄存器和运行时栈,对程序员来说是直接可见的。本书仅提供了低级操作来支持数据处理和程序控制。编译器必须用多条指令来产生和操作各种数据结构,来实现像条件、循环和过程这样的控制结构。我们讲述了C语言和如何编译它的许多不同方面。我们看到C语言中缺乏边界检查,使得许多程序容易出现缓冲区溢出。虽然最近的运行时系统提供了安全保护,而且编译器帮助使得程序更安全,但是这已经使许多系统容易受到入侵者的恶意攻击。
第4章 处理器体系结构
△我们已经看到,指令集体系结构,即ISA,在处理行为和如何实现处理器之间提供了一层抽象。ISA提供了程序执行器行为的一种顺序说明,也就是一条指令执行完了,下一条指令才会开始。从IA32指令开始,大大简化数据类型、地址模式和指令编码,我们定义了Y86指令集。得到的ISA既有RISC指令集的属性,也有CISC指令集的属性。然后,将不同指令组织放到五个阶段中处理,在此,根据被执行指令的不同,每个阶段中的操作也不相同。据此,我们构造了SEQ处理器,其中每个时钟周期执行一条指令,它会通过所有五个阶段。
流水线化通过让不同的阶段并行操作,改进了系统的吞吐量性能。在任意一个给定的时刻:多条指令被不同的阶段处理。在引入这种并行性的过程中,我们必须非常小心,以提供与程序的顺序执行相同的程序级行为。通过重新调整SEQ各个部分的顺序,引入流水线,我们得到SEQ+,接着添加流水线寄存器,创建出PIIE―流水线。然后,添加了转发逻辑,加速了将结果从一条指令发送到另一条指令,从而提高了流水线的性能。有几种特殊情况需要额外的流水线控制逻辑来暂停或取消一些流水线阶段。
在本章中,我们学习了有关处理器设计的几个重要经验:
1.管理复杂性是首要问题,想要优化使用硬件资源,在最小的成本下获得最大的性能。为了实现这个目的,我们创建了一个非常简单而一致的框架,来处理所有不同的指令类型。有了这个框架,就能够在处理不同指令类型的逻辑中共享硬件单元。
2.我们不需要直接实现ISA。它的直接实现意味着一个顺序的设计。为了获得更高的性能我们想运用硬件能力以同时执行许多操作,这就导致要使用流水线化设计。通过仔细设计和分析,我们能够处理各种流水线冒险,因此运行一个程序的整体效果,同用ISA模型获得的效果完全一致。
3.硬件设计人员必须非常谨慎小心。一旦芯片制造出来,就几乎不可能改正任何错误了。开始就使设计正确是非常重要的。这就意味着要仔细地分析各种指令类型和组合,甚至那些看上去没有意义的情况,例如弹出值到栈指针。必须用系统的模拟测试程序彻底地测试设计。在开发PIPE的控制逻辑中,我们的设计有个细微的错误,只有通过对控制组合的仔细而系统的分析才能发现。
第6章 存储器层次结构
△基本存储技术包括随机存储器(RAM)、非易失性存储器(即OM)和磁盘。RAM有两种基本类型。静态RAM(SRAM)快一些,但是也贵一些,它既可以用做CPU芯片上的高速缓存,也可以用做芯片下的高速缓存。动态RAM(DRAM)慢一些,也便宜一些,用做主存和图形帧缓冲区。非易失性存储器,也称为只读存储器(ROM)即使是在关电的时候,也能保持它们的信息,它们用来存储固件。旋转磁盘是机械的非易失性存储设备,以每个位很低的成本保有大量的数据,但是访问时间比DRAM更长。固态硬盘(SSD基于非易失性的闪存,越来越变成旋转磁盘对某些应用的具有吸引力的替代产品。
一般而言,较快的存储技术每个位的价格会更高,而且容量较小。这些技术的价格和性能属性正在以显著不同的速度变化着。特别地,DRAM和磁盘访问时间远远大于CPU周期时间。系统通过将存储器组织成存储设备的层次结构来弥补这些差异,在这个层次结构中,较小、较快的设备在顶部,较大、较慢的设备在底部。因为编写良好的程序有好的局部性,大多数数据都可以从较高层得到服务,结果就是存储系统能以较高层的速度运行,但却有较低层的成本和容量。
程序员可以通过编写有良好空间和时间局部性的程序来显著地改进程序的运行时间。利用基于SRAM的高速缓存存储器特别重要。
标签:
原文地址:http://www.cnblogs.com/bonjourvivi/p/4928380.html