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.规则:
3.匹配方法:
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的数字
作为实数运算的近似值
小数的二进制表示法只能表示那些能够被写成x X (2^y)的数,其他的值只能近似的表示。 (1)权重
以小数点为界:
左边第i位,权重为2的i次幂
右边第i位,权重为1/2的i次幂
用V=(-1)^s X 2^E X M 来表示一个数:
符号:s决定这个数是正还是负。0的符号位特殊情况处理。
阶码:E对浮点数加权,权重是2的E次幂(可能为负数)
尾数:M是一个二进制小数,范围为1~2-ε或者0~1-ε(ε=1/2的n次幂)
单独符号位s编码符号s,占1位
k位的阶码字段exp编码阶码E
n位小数字段frac编码尾数M(同时需要依赖阶码字段的值是否为0)
舍入运算:找到和数值x最接近的匹配值x',可以用期望的浮点形式表示出来。
IEEE浮点格式定义了四种不同的舍入方法:
即:将数字向上或向下舍入,是的结果的最低有效数字为偶数。
能用于二进制小数。
即:把整数向下舍入,负数向上舍入。
正数和负数都向下舍入。
正数和负数都向上舍入。
gcc -01 -o p p1.c
GCC将源代码转化为可执行代码的步骤:
C预处理器——扩展源代码-生成.i文件
编译器——产生两个源代码的汇编代码-——生成.s文件
汇编器——将汇编代码转化成二进制目标代码——生成.o文件
链接器——产生可执行代码文件
(1)操作数:指示出执行一个操作中要引用的源数据值,以及放置结果的目标位置。
a.操作数的三种类型
(2)结果存放的两种可能
a.功能
把一个字节(字)操作数从源SRC传送至目的地DST
b.格式
MOV DST,SRC
(2) push&pop
a.压栈push
功能:把数据压入到栈上
b.出栈pop
功能:弹出数据
都只有一个操作数。
(1)c操作符*执行指针的间接引用。
(2)c语言中的指针其实就是地址,间接引用指针就是将该指针放在一个寄存器中,然后在存储器引用中使用这个寄存器
(3)局部变量通常保存在寄存器中,而不是存储器
栈用来传递参数、存储返回信息、保存寄存器,以及本地存储。
为单个过程分配的那部分栈帧。
最顶端的栈帧以两个指针界定:
寄存器%ebp-帧指针
寄存器%esp-栈指针
栈指针可移动,所以信息访问多相对于帧指针。
ret指从栈中弹出地址,并跳转到这个位置。
这个指令可以使栈做好返回的准备,等价于:
movl %ebp,%esp
popl %ebp
Y86指令集基本上是IA32指令集的一个子集,只包括四字节整数操作,寻址方式比较少,操作也较少。
目的可以是寄存器(i)或存储器(m)。
指令名字的第一个字母就表明了源的类型,指令名字的第二个字母就指明了目的类型。
注意:
a.它们只对寄存器数据进行操作(I32还允许对存储器数据进行操作)。
b.这些指令会设置三个条件码:ZF,SF和OF(零,符号和溢出)。
jmp,jle,jl,je,jne,jge和jg。
cmovle,cmovl,cmove,cmovne,cmovge和cmovg.
只有当条件码妈祖所需要的约束时,才会更新目的寄存器的值。
call指令将返回地址入栈,然后跳到目的地址。ret从这样的过程调用中返回。
实现了入栈和出栈。
a.停止指令的执行。
b.执行halt指令会导致处理器停止,并将状态码设置为HLT。
a.描述程序执行的总体状态。
b.AOK 正常操作
两个特别的指令:pushl和popl 通常有两种约定
(1)压入%esp的原始值。
(2)压入减去4的%esp得出值。
SEQ处理器
(1)阶段
详细内容见书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
a.由盘片构成,每个盘片有两面或者称为表面,表面覆盖着磁性记录材料,盘中央有一个可以旋转的主轴,使得盘片以固定的旋转速率旋转,磁盘通常包含一个或者多个这样的盘片,冰封装在一个密封的容器内。
b.每个表面由一组称为磁道的同心圆组成的。每个磁道被划分为一组扇区,每个扇区包含相等数量的数据位(512字节),扇区之间由一些间隙分隔开,间隙间不存储数据位。间隙存储用来标识扇区的格式化位。
a.最大容量(容量):一个磁盘上可以记录的最大位数。
b.决定因素:
c.公式:
a.磁盘是以扇区大小的块来读写数据。
b.访问时间:
最大旋转延迟:T(max rotation) = (1/RPM)*(60secs/1min)
平均旋转时间:T(avg rotation)=1/2T(max rotation)
l 传送时间:一个扇区的传送时间依赖于旋转速度和每条磁道的扇区数目。
T(avg transfer)= (1/RPM)*(1/(平均扇区数/磁道))*(60secs/1min)
注意:
a.一个B个扇区大小的逻辑快的序列,编号为0,1,….,B-1。
b.磁盘中有一个小的硬件/固件设备,称为磁盘控制器。维护着逻辑块号和实际磁盘扇区之间的映射关系。
两种形式:时间局部性和空间局部性
(1)顺序引用模式:步长为1的引用模式。
(2)c数组在存储器中是按照行顺序来存放的。
(1)代码区别于程序数据的一个重要属性是在运行时它是不能被修改的。
(2)当程序正在执行时,CPU只从存储器中读出它的指令。CPU决不会重写或修改这些指令。
存储器层次结构中的缓存
存储器层次结构的中心思想:对于每个k,位于k层的更快更小的存储设备作为位于k+1层的更大更慢的存储设备的缓存。
当程序需要第k+1层的某个数据对象d时,首先在当前存储在第k层的一个块中查找d,如果d刚好缓存在第k层中,就称为缓存命中。
(1)即第k层中没有缓存数据对象d。
这时第k层缓存会从第k+1层缓存中取出包含d的那个块。如果第k层缓存已满,就可能会覆盖现存的一个块
覆盖一个现存的块的过程称为替换或驱逐。
(1)强制性不命中/冷不命中
即第k层的缓存是空的(称为冷缓存),对任何数据对象的访问都不会命中。
(2)冲突不命中
由于一个放置策略:将第k+1层的某个块限制放置在第k层块的一个小的子集中,这就会导致缓存没有满,但是那个对应的块满了,就会不命中。
(3)容量不命中
当工作集的大小超过缓存的大小时,缓存会经历容量不命中,就是说缓存太小了,不能处理这个工作集。
某种形式的逻辑必须管理缓存,而管理缓存的逻辑可以是硬件、软件,或者两者的集合。
(1)高速缓存是一个高速缓存组的数组(S,E,B,m)
S:这个数组中有S=2^s个高速缓存组
E:每个组包含E个高速缓存行
B:每个行是由一个B=2^b字节的数据块组成的
m:每个存储器地址有m位,形成M=2^m个不同的地址
(2)标记位和有效位
通过在实验楼和所安装的linux虚拟机上不断训练学习,很好地掌握了linux操作系统vim编辑器三种模式的基本操作,在linux操作系统的环境下进行C语言编程及利用gdb进行调试,学会使用makefile文件管理器静态库和共享库的制作等等内容。
通过对书本所学习的六章内容中对linux基础、信息的的表示和处理、程序的机器级表示、处理器体系结构和储存器有了较为深刻的认识,以前对这些内容或是一知半解或者是一窍不通,现在通过日积月累已经基本理解其中的一些基本理论知识
通过实践中总结和体会,得出一些经验,从而形成的活跃的一种思维方式,学会通过一些指令的用法引申到另外的指令,通过在linux系统编程使用的一些方法可以和windows系统对比使用,如静态库的建立等,也就是娄老师常说的“举一反三”的能力和技巧。
2.查询知识,自主学习
大学生应该掌握自主学习的能力和技巧,不要一遇到问题就问老师或者放弃,在学习Linux命令的时候,老师就强调man、cheat、find......这一系列帮助文档、查找工具的重要性。就像百度一样,在Linux中,有问题就可以去找man,查找东西可以locate,某个命令的man看不懂还可以cheat,尽量通过自己的搜索一步步的解决问题,而不是不动脑子的照搬。如果让我们自己去学会搜索需要的东西,发现很多知识原来并不是我们想像中的那么难,只是我们的学习方法和学习态度不对而已。
对一些最基本的、具有高复用性的知识进行归纳和总结,温故知新,日积月累。
1.首先,我很认同老师这种教学方法,能促进同学们积极主动地学习和实践,所谓“授之以鱼不如授之以渔”,娄老师不是把 知识灌溉给我们,而是让我们学会如何自主地获取知识和掌握知识,让学生学会举一反三的能力,这些很多别的课程所欠缺的一种教学技巧,可以说这门课学习氛围很好。
2.然而,很多知识学生不了解的知识应该在课堂上加强讲解,对于很多同学都掌握不太好的知识尽量少让学生去讲,因为学生毕竟讲课没有老师有经验,而且有时候一个知识点需要很长的时间来说明,并且有一些不对的地方还需要老师来纠正,这样既造成大家上课的效率很低。
3.我认为很多时候可以不要把分数与这门课所有学习的内容过程挂钩,这样会更造成学生是为了分数而学习,不是为了学习而学习,适当的分数统计会激励学生,可是会造成很多学生就只是为了完成老师所布置的任务哪部分取得相应的的分数,而不再去深入学习其他的内容。
1.20135223何伟钦(即本人)这学期的博客(第一周—第六周的博客)http://www.cnblogs.com/20135223heweiqin/
2.《深入理解计算机系统》前七章内容
3.信息安全系统设计基础@BESTI http://group.cnblogs.com/bocsd/
4.每周作业解析 http://group.cnblogs.com/topic/73060.html