信息安全系统设计基础第七周学习总结

第一周

 

第二周

:tabe fn     在一个新的标签页中编辑文件fn gt     切换到下一个标签页 gT     切换到上一个标签页 :tabr     切换到第一个标签页 :tabl     切换到最后一个标签页 :tabm [N]     把当前tab移动到第N个tab之后 对,正如你所想象的那样,跟eclipse, ue等的标签页是一个意思! 窗口命令 ctrl+w s     水平分割窗口 ctrl+w w     切换窗口 ctrl+w q     退出当前窗口(由于同时有多个文件,此命令不会影响其他窗口) ctrl+w v     垂直分割窗口
:w     将缓冲区写入文件,即保存修改 :wq     保存修改并退出 :x     保存修改并退出 :q     退出,如果对缓冲区进行过修改,则会提示 :q!     强制退出,放弃修改 查找替换 /pattern     向后搜索字符串pattern ?pattern     向前搜索字符串pattern n     下一个匹配(如果是/搜索,则是向下的下一个,?搜索则是向上的下一个) N     上一个匹配(同上) :%s/old/new/g     搜索整个文件,将所有的old替换为new :%s/old/new/gc     搜索整个文件,将所有的old替换为new,每次都要你确认是否替换 复制粘贴 dd     删除光标所在行 dw     删除一个字(word) x     删除当前字符 X     删除前一个字符 D     删除到行末 yy     复制一行,此命令前可跟数字,标识复制多行,如6yy,表示从当前行开始复制6行 yw     复制一个字 y$     复制到行末 p     粘贴粘贴板的内容到当前行的下面 P     粘贴粘贴板的内容到当前行的上面 ]p     有缩进的粘贴,vim会自动调节代码的缩进 "a     将内容放入/存入a寄存器,可以支持多粘贴板
h,j,k,l     上,下,左,右 ctrl-f     上翻一页 ctrl-b     下翻一页 %     跳到与当前括号匹配的括号处,如当前在{,则跳转到与之匹配的}处 w     跳到下一个字首,按标点或单词分割 W     跳到下一个字首,长跳,如end-of-line被认为是一个字 e     跳到下一个字尾 E     跳到下一个字尾,长跳 b     跳到上一个字 B     跳到上一个字,长跳 0     跳至行首,不管有无缩进,就是跳到第0个字符 ^     跳至行首的第一个字符 $     跳至行尾 gg     跳至文件的第一行 gd     跳至当前光标所在的变量的声明处 [N]G     跳到第N行,如0G,就等价于gg,100G就是第100行 fx     在当前行中找x字符,找到了就跳转至 ;     重复上一个f命令,而不用重复的输入fx tx     与fx类似,但是只是跳转到x的前一个字符处 Fx     跟fx的方向相反 ),(     跳转到上/下一个语句 *     查找光标所在处的单词,向下查找 #     查找光标所在处的单词,向上查找 `.     跳转至上次编辑位置 在屏幕上移动
H     移动光标到当前屏幕上最上边的一行 M     移动光标到当前屏幕上中间的一行 L     移动光标到当前屏幕上最下边的一行 书签 ma     把当前位置存成标签a `a     跳转到标签a处 编辑 r     替换一个字符 J     将下一行和当前行连接为一行 cc     删除当前行并进入编辑模式 cw     删除当前字,并进入编辑模式 c$     擦除从当前位置至行末的内容,并进入编辑模式 s     删除当前字符并进入编辑模式 S     删除光标所在行并进入编辑模式 xp     交换当前字符和下一个字符 u     撤销 ctrl+r     重做 .     重复上一个编辑命令 ~     切换大小写,当前字符 g~iw     切换当前字的大小写 gUiw     将当前字变成大写 guiw     将当前字变成小写 >>     将当前行右移一个单位 <<     将当前行左移一个单位(一个tab符) ==     自动缩进当前行
插入模式 i     从当前光标处进入插入模式 I     进入插入模式,并置光标于行首 a     追加模式,置光标于当前光标之后 A     追加模式,置光标于行末 o     在当前行之下新加一行,并进入插入模式 O     在当前行之上新加一行,并进入插入模式 Esc     退出插入模式 可视模式 标记文本 v     进入可视模式,单字符模式 V     进入可视模式,行模式 ctrl+v     进入可视模式,列模式,类似于UE的列模式 o     跳转光标到选中块的另一个端点 U     将选中块中的内容转成大写 O     跳转光标到块的另一个端点 aw     选中一个字 ab     选中括号中的所有内容,包括括号本身 aB     选中{}括号中的所有内容 ib     选中括号中的内容,不含括号 iB     选中{}中的内容,不含{}
对标记进行动作 >     块右移 <     块左移 y     复制块 d     删除块 ~     切换块中内容的大小

2. gcc

GNU CC(简称为gcc)是GNU项目中符合ANSI C标准的编译系统,能够编译用C、C++和Object C等语言编写的程序。gcc又是一个交叉平台编译器,它能够在当前CPU平台上为多种不同体系结构的硬件平台开发软件,因此尤其适合在嵌入式领域的开发编译。

GCC编译代码的过程如下:

 

我们可以把编译过程分成四步,以编译hello.c生成可执行文件hello为例,如下图:

  • 预处理: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

编译过程比较难记,我们简化一下,前三步,GCC的参数连起来是“ESc”,相应输入的文件的后缀是“iso”,这样记忆起来就容易多了。

学习GCC的另外一个重点是:参考教材《深入理解计算机系统》 7.6,7.10节,学习静态库,动态库的制作。

info b 查看所设断点

break 行号或函数名 <条件表达式> 设置断点

tbreak 行号或函数名 <条件表达式> 设置临时断点,到达后被自动删除

delete [断点号] 删除指定断点,其断点号为”info b”中的第一栏。若缺省断点号则删除所有断点

disable [断点号]] 停止指定断点,使用”info b”仍能查看此断点。同delete一样,省断点号则停止所有断点

enable [断点号] 激活指定断点,即激活被disable停止的断点

condition [断点号] <条件表达式> 修改对应断点的条件

ignore [断点号]<num> 在程序执行中,忽略对应断点num次

step 单步恢复程序运行,且进入函数调用

next 单步恢复程序运行,但不进入函数调用

finish 运行程序,直到当前函数完成返回

c 继续执行函数,直到函数结束或遇到新的断点

由于设置断点在Gdb的调试中非常重要,所以在此再着重讲解一下Gdb中设置断点的方法。

Gdb中设置断点有多种方式:其一是按行设置断点,设置方法在3.5.1节已经指出,在此就不重复了。另外还可以设置函数断点和条件断点,在此结合上一小节的代码,具体介绍后两种设置断点的方法。

① 函数断点

(gdb) b 函数名

② 条件断点

格式为:b 行数或函数名 if 表达式

(gdb) b 8 if i==10

3. gdb

2.1预处理

 

可以输出test.i文件中存放着test.c经预处理之后的代码。打开test.i文件,看一看,就明白了。后面那条指令,是直接在命令行窗口中输出预处理后的代码.

gcc的-E选项,可以让编译器在预处理后停止,并输出预处理结果。在本例中,预处理结果就是将stdio.h 文件中的内容插入到test.c中了。

2.2编译为汇编代码(Compilation)

预处理之后,可直接对生成的test.i文件编译,生成汇编代码:

gcc的-S选项,表示在程序编译期间,在生成汇编代码后,停止,-o输出汇编代码文件。

2.3汇编(Assembly)

对于上一小节中生成的汇编代码文件test.s,gas汇编器负责将其编译为目标文件,如下:

2.4连接(Linking)

gcc连接器是gas提供的,负责将程序的目标文件与所需的所有附加的目标文件连接起来,最终生成可执行文件。附加的目标文件包括静态连接库和动态连接库。

对于上一小节中生成的test.o,将其与C标准输入输出库进行连接,最终生成程序test

 

在命令行窗口中,执行./test, 让它说HelloWorld吧!

建议使用CGDB,比GDB好用,熟悉VC的调试方式,可以使用DDD。 注意使用GCC编译时要加“-g”参数。 参考gdb参考卡GDB最基本的命令有:

  • gdb programm(启动GDB)
  • b 设断点(要会设4种断点:行断点、函数断点、条件断点、临时断点)
  • run 开始运行程序
  • bt 打印函数调用堆栈
  • p 查看变量值
  • c 从当前断点继续运行到下一个断点
  • n 单步运行
  • s 单步运行
  • quit 退出GDB

4.其他

display 跟踪变量值的改变

until 跳出循环

finish 跳出函数

help 帮助

第三周

一、数字表示

    1、 无符号数:编码基于传统的二进制表示法表示大于或等于零的数字。

    2、 补码:编码是表示有符号整数的最常见方法,可以是正或者是负的数字。

    3、 浮点数:编码是表示实数的科学计数法的以二位基数的版本。 

  • 三种数字:无符号数、有符号数(2进制补码)、浮点数
  •  溢出:计算机的表示法是用有限数量的位来对一个数字编码,当结果太大以至不能表示时,会溢出
  • 整数运算:编码的数值范围较小,精确;浮点运算:数值范围较大,近似,不可结合

 

§1 信息存储

 

  • 最小的可寻址的存储器单位:字节(8位)
  • 虚拟存储器、地址、虚拟地址空间(p22)

 

进制转换

十六进制表示法

十六进制中一个字节的值域为00H~FFH

 

用0x或0X开头表示十六进制数字常量

快捷算法:要表示的数字常量为x=2^n,n=i+4j,且0≤i≤3时,开头的十六进制数字为1(i=0)、2(i=1)、4(i=2)、8(i=3),后面跟随着j个十六进制的0。这里的j是代表着每四位二进制位对应的十六进制位,而i的范围是因为十六进制中每一位的范围是0-F

二、字

字长:指明整数和指针数据的标称大小。决定虚拟地址空间的最大大小

字长为w,虚拟地址范围为0~2^w-1,程序最多访问2^w个字节,cpu一次处理w位数据

 

三、数据大小

在不同字长的计算机中,相同的数据类型所占用的字节数不同

在64位机上生成32位代码:gcc -m32

32位与64位机器中的数据大小

C声明

32位机器

64位机器

char

1

1

short int

2

2

int

4

4

long int

4

8

long long int

8

8

char *

4

8

float

4

4

double

8

8

 

四、寻址和字节顺序

 

多字节对象倍存储为连续的字节序列,对象的地址为所使用字节中最小的地址

 

字节顺序是网络编程的基础

 

1.两个通用规则(w为整数,位表示为[Xw-1,Xw-2,……,X1,X0],其中Xw-1是最高有效位,X0是最低有效位):

 

  • 小端法:最低有效字节在最前面(大多数Intel兼容机)
  • 大端法:最高有效字节在最前面(大多数IBM和Sun Microsystems机器)
  • 一些新的微处理器使用双端法

 

字节内部的顺序不变

 

反汇编器:确定可执行程序文件所表示的指令序列的工具;将可执行程序文件转换回可读性更好的ASCII码形式的程度

 

2.强制类型转换

 

 

表示字符串

c语言中字符串被编码成为一个null(值为0)字符结尾的字符数组

命令man ascii:得到ASCII字符码表

 

表示代码

二进制代码在不同的操作系统上有不同的编码规则。所以二进制代码是不兼容的

 

布尔代数

1.最简单布尔代数:与& 或| 非~ 异或^(结果为0或1)

2.扩展的布尔运算:位向量的运算(结果仍是位向量)

位向量的应用:表示有限集合,对集合编码

 

位级运算

1.将位向量按位进行逻辑运算,结果仍是位向量

2.掩码运算

掩码:用来选择性的屏蔽信号,是一个位模式,表示从一个字中选出的位的集合。

用位向量给集合编码,通过指定掩码来有选择的屏蔽或者不屏蔽一些信号,某一位位置上为1时,表明信号i是有效的;0表示该信号被屏蔽。这个掩码就表示有效信号的集合。

0xFF:屏蔽除最低有效字节之外的所有字节。

~0:生成全1的掩码

 

逻辑运算

1.逻辑运算符:与&&  或||  非!

2.计算方法:所有非零参数都代表TRUE,0参数代表FALSE。1代表TRUE,0代表FALSE

  • 只有当参数被限制为0或1时,逻辑运算才与按位运算有相同的行为。
  • 如果对第一个参数求值就能确定表达式的结果,逻辑运算符就不会对后面的参数求值。

移位运算

C语言还提供了一组移位运算,以便向左或向右移动位模式。移位运算可以从左向右结合的,所以x<<j<<k等价于(x<<j)<<k。

一般而言,机器支持两种形式的右移:逻辑右移和算数右移。逻辑右移在最左端补k个0,算数右移在最左端补k各最高有效位的值。

C语言标准没有明确定义应该使用哪种类型的右移。对于无符号数据,右移必须是逻辑的。对于有符号数据,算数的或者逻辑的右移都可以。

 

C语言中有符号数和无符号数的转换

位向量不变,只是上下文的读取方式不同,所以根据不同的读取规则,最终的读取结果也不同。这就是所谓的信息就是位+上下文。

注:c语言中要创建一个无符号常量,必须加上后缀字符'U'或者'u'。

  转换的原则是底层的位表示保持不变。

怎么让负数等于正数

 将有符号负数转化为无符号正数,变的只是上下文的读取方式,但二进制位级表示是一样的。

零扩展和符号扩展

零扩展:将一个无符号数转换为一个更大的数据类型,我们只需要简单地在开头添加0。

号扩展:将一个补码数字转换为一个更大的数据类型,规则是在表示中添加最高有效位的值的副本。

无符号数与有符号数容易造成的错误

例:以下一段代码

float sum_elements(float a[],unsigned length){

 

    int i;

 

    float result=0;

 

    for(i=0;i<=length-1;i++)

 

        result+=a[i];

 

    return result;

 

}

因为参数length是无符号的,计算0-1将进行无符号运算,这等价于模数加法。结果得到UMax。<=比较进行同样使用无符号数比较,而因为任何数都是小于或者等于UMax的,所以这个比较总是为真!因此,代码将试图访问数组a的非法元素。

改正方法:1.将length声明为int类型。

2.或将for循环的测试条件改为i<length。

整数溢出

整数溢出:指完整的整数结果不能放到数据类型限制的字长中去。

避免整数溢出:当两个整数进行运算时,其结果用更大的数据类型进行存储。比如两个int类型的整数相乘的结果用long long数据类型的变量来存储。

关于整数运算的思考

计算机执行的"整数"运算实际上是一种模运算形式。表示数字的有限字长限制了可能的值的取值范围,结果运算可能溢出。

补码提供了一种既能表示负数也能表示正数的灵活方法,同时使用了与执行无符号算数相同的位级实现,这些运算包括加减乘除,无论是以无符号形式还是以补码形式表示的,都有完全一样或者非常类似的位级行为。

浮点数

浮点表示对形如V=x*的有理数进行编码。它对涉及非常大的数字(|    V|>>0)、非常接近于0(|V|<<1)的数字,以及更普遍地作为实数运算的近似值的计算,是很有用的。

浮点数的运算及执行标准:IEEE标准754。

 浮点数运算的不精确性和舍入

  当一个数字不能精确地表示为IEEE标准754时,就必须向上或者向下调整,此时出现舍入。

 IEEE浮点标准,float和double类型p70

    单精度浮点格式(float)中,s、exp和frac字段分别为1位、k=8位和n=23位,得到一个32位的表示。

    双精度浮点格式(double)中,s、exp和frac字段分别为1位、k=11位和n=52位,得到一个64位的表示。

整数与浮点数转换规则

当在int、float和double格式之间进行强制类型转换时,程序改变数值和位模式的原则如下(假设int是32位的):

  1. 从int转换成float,数字不会溢出,但是可能被舍入。
  2. 从int或float转换成double,因为double有更大的范围(也就是可表示值的范围),也有更高的精度(也就是有效位数),所以能够保留精确的数值。
  3. 从double转换成float,因为范围要小一些,所以值可能溢出为+∞或-∞。另外由于精确度较小,它还可能被舍入。
  4. 从float或者double转换为int,值将会向零舍入。

 

第四周

1.P104\P105

X86 寻址方式经历三代:

-DOS时代的平坦模式,不区分用户空间和内核空间,很不安全

-8086的分段模式

-IA32的带保护模式的平坦模式

2.P106

ISA:机器级程序的格式和行为,定义为指令集体系机构,它定义了处理器状态指令的格式,以及每条指令对状态的影响。

 机器级程序使用的存储器地址是虚拟地址,提供的存储器模型看上去是一个非常大的字符数组

PC:程序计数器。在IA32中,用%eip表示,指示将要执行的下一条指令在存储器中的地址。

程序存储器:包含程序的可执行机器代码,操作系统需要的一些信息,用来管理过程调用和返回的运行时栈,以及用户分配的存储器块。

3.P107

64位机上想得到32位代码:gcc -m32 -S xxx.c

编译并产生汇编目标文件xxx.o:gcc -O1 -c xxx.c

获得汇编代码:gcc -S xxx.c -o xxx.s

Ubuntu中获得汇编代码:gcc -S xxx.c更接近教材

教材中获得汇编代码:gcc -O1 -S xxx.c(编译器使用的事第一级优化)

 

4.P108

 二进制文件可用od命令查看,也可以用gdb的x查看:(gdb)x/17xb sum表示检查17个十六进制的字节;

 显示代码过多或过少可用more、less结合管道查看,也可以用输出重定向:

 od xxx.o | more

 od xxx.o > xxx.txt

5.P109

gcc -S 产生的汇编中可以把 以”.“开始的语句都删除了再阅读

 6.P110

 Linux和windows的汇编格式的区别:

 -Intel代码省略了指示大小的后缀,即'l'

 -Intel代码省略了寄存器名字前面的‘%’符号,用的是esp,而不是%esp

 -Intel代码用不同的方式来描述存储器中位置

 -在带有多个操作数的指令情况下,列出操作数的顺序相反

7.P111

 -db char 1

-dw short int 2

-dd int 或float 4

-dq long int 或 double 8

8.P112

-esi、edi可以用来操纵数组,esp、ebp用来操纵栈帧。

-通用寄存器中的eax,ebx,ecx,edx中,32位的eax,16位的ax,8位的ah,al都是独立的。例如:假定当前是32位x86机器,eax寄存器的值为0x8226,执行完addw $0x8266, %ax指令后eax的值是多少?

解析:0x8226+0x826=0x1044c, ax是16位寄存器,出现溢出,最高位的1会丢掉,剩下0x44c,不要以为eax是32位的不会发生溢出。

多数情况下,前6个寄存器为通用寄存器,最后两个寄存器保存着指向程序栈中重要位置的指针。

另外,字节操作指令可以独立的读或者写前4个寄存器的2个低位字节。

9.P113

操作数的三种类型:立即数(常数值)、寄存器(某个寄存器的内容)、存储器(根据计算出来的地址访问某个存储器位置)

-有效地址的计算方式 Imm(Eb,Ei,s) = Imm + R[Eb] + R[Ei]*s

 

10.P114

-MOV:相当于C语言的赋值“=”,将源操作数的值复制到目的操作数中;

 MOVS:将一个较小的源数据复制到一个较大的数据位置,高位用位扩展;

 MOVZ:将一个较小的源数据复制到一个较大的数据位置,高位用零扩展。

-push:把数据压入栈中;

 pop:删除数据。

11.P115\P116

 -栈顶元素的地址是所有栈中元素地址中最低的

-栈指针%esp保存栈顶元素的地址。

 

12.P117

 -指针就是地址

-局部变量保存在寄存器中

13.P119

按目的操作数分类:

第一类:加载有效地址。实际是将有效地址写入目的操作数,目的操作数必须是寄存器。

第二类:一元操作。操作数既是源又是目的。可以是寄存器也可以是存储器。

第三类:二元操作。第二个操作数既是源又是目的。但两个操作数不能同时是存储器。

第四类:移位操作。位移量是一个立即数或放在单字节寄存器%cl中。移位操作的目的操作数可以是一个寄存器或是一个存储器位置。

14.P123\P124

 有条件跳转(实现if,switch,while,for)

 无条件跳转jmp(实现goto)

 

15.P125

SET指令根据t=a-b的结果设置条件码

 16.P127

跳转指令(导致执行切换到程序中一个全新的位置,跳转的目的地通常用一个标号指明)

无条件跳转:JMP 可以是直接跳转也可以是间接跳转(写法是*后面加操作数指示符)

 有条件跳转:根据条件码的某个组合,或者跳转或者继续执行下一条指令

17.P130-P145

-条件分支——if-else结构:在两个分支语句中选择执行一个,汇编实现通过goto,就是汇编器为两个分支产生各自的代码块,它会插入条件和无条件分支,以保证能执行正确的代码块。

-循环结构——do-while、while、for:用条件测试和跳转组合实现循环的效果。大多数汇编器根据do-while形式来产生循环代码,其他的循环会首先转换成do-while形式,然后再编译成机器代码。

-switch语句:根据一个整数索引值进行多重分支。通过使用跳转表这种数据结构实现更加高效。跳转表是一个数组,表项i是一个代码段的地址,这个代码段实现当开关索引值为i时程序该做的。此时跳转可以用goto/jmp

18.P149

IA32通过程序栈来实现过程调用

19.P150\P151

call指令\ret指令

函数返回值存在%eax

 

 

20.P174

关于栈帧的gdb命令bt/frame/up/down

命令

描述

backtrace(或bt)            

查看各级函数调用及参数

finish

连续运行到当前函数返回为止,然后停下来等待命令

frame(或f) 帧编号

选择栈帧

info(或i) locals

查看当前栈帧局部变量的值

list(或l)

列出源代码,接着上次的位置往下列,每次列10行

list 行号

列出从第几行开始的源代码

list 函数名

列出某个函数的源代码

next(或n)

执行下一行语句

print(或p)

打印表达式的值,通过表达式可以修改变量的值或者调用函数

quit(或q)

退出gdb调试环境

set var

修改变量的值

start

开始执行程序,停在main函数第一行语句前面等待命令

step(或s)

执行下一行语句,如果有函数调用则进入到函数中    

break(或b) 行号             

在某一行设置断点                                                                       

break 函数名

在某个函数开头设置断点

break ... if ...

设置条件断点

continue(或c)

从当前位置开始连续运行程序

delete breakpoints

删除断点

display 变量名

跟踪查看某个变量,每次停下来都显示它的值

disable breakpoints

禁用断点

enable 断点号

启用断点

info(或i)breakpoints

查看当前设置了哪些断点

run(或r)

从头开始连续运行程序

undisplay 跟踪显示号

取消跟踪显示

watch                                  

设置观察点     

info(或i) watchpoints

查看当前设置了哪些观察点  

x

从某个位置开始打印存储单元的内容,全部当成字节来看,   

 而不区分哪个字节属于哪个变量

 

第五周

4.1 Y86指令集体系结构

一、程序员可见的状态

程序员可见状态:程序中的每条指令都会读取或修改处理器状态的某些部分

--8个程序寄存器:%eax,%ecx,%edx,%ebx,%esi,%edi,%esp,%ebp.他们都可以存储一个字;

%esp被入栈、出栈、调用和返回指令作为栈指针;

其他情况时寄存器没有固定的含义或固定值

--3个一位条件码:ZF、OF、SF.保存最近的算术或逻辑指令所造成影响的有关信息

--PC(程序计数器):存放当前正在执行指令的地址。

--存储器:一个很大的字节数组,保存着程序和数据;

Y86用虚拟地址来引用存储器位置,硬件和操作系统软件联合起来将虚拟地址翻译成实际或物理地址,指明数据实际保存在存储器中哪个地方

--Stat:状态码,程序状态的最后一个部分,表明程序执行的总体状态,指示是正常运行还是出现了某种异常

二、Y86指令

--halt:这个指令将会终止指令的执行。

--nop:这是一个占位指令,它不做任何事情,后续为了实现流水线,它有一定的作用。

--xxmovl:这是一系列的数据传送指令,其中r代表寄存器,m代表存储器,i代表立即数。比如rrmovl指令,则代表将一个寄存器的值,赋给另外一个寄存器。

--opl:操作指令,比如加法,减法等等。

--jxx:条件跳转指令,根据后面的条件进行跳转。

--cmovxx:条件传送指令,后面的xx代表的是条件。特别的是,条件传送只发生在两个寄存器之间,不会将数据传送到存储器。

--call与ret:方法的调用和返回指令。一个将返回地址入栈,并跳到目标地址。一个将返回地址入PC,并跳到返回地址。

--push与pop:入栈和出栈操作。

三、指令编码

--对于opl、jxx、cmovxx指令来说,都有一个fn标识,占用4个二进制位(半个字节)。这个便是指令的功能部分,这个是由于它们的指令编码一样,但功能有所不同所造成的。比如对于opl,就有加、减、与、异或等操作,那么它们的指令编码第一个字节就分别为十六进制的60、61、62、63。

--Y86指令集图中可看见指令的字节级编码。每条指令需要1-6个字节不等。每条指令的第一个字节表明指令的类型。这个字节分为两个部分,每部分4位:高4位是代码部分,低4位是功能部分。功能值只有在一组相关指令共用一个代码时才有用。

--有的指令只有一个字节长,因为可能附加有寄存器指示符字节,指定一个或两个寄存器。这些寄存器字段为rA,rB。有则有,无则无,只有一个的则将第二个设为0xF。

四、Y86异常

--对于Y86来说,程序猿可见的状态中就有stat状态码,它标识了程序执行的状态。Y86需要有能力根据stat去做一些处理。不过为了简单起见,这里除了正常执行之外,都将停止指令的执行。真实当中,会有专门的异常处理程序。

--Y86有四种不同的状态码,AOK(正常)、HLT(执行halt指令)、ADR(非法地址)和INS(非法指令)。

五、Y86程序和Y86指令详情

--比如对于X86指令中的 addl $4,%ecx 这样的指令,由于Y86当中的addl指令中不包含立即数,所以Y86需要先将立即数存入寄存器,即使用irmovl指令,然后再使用addl来处理加法运算。

--创建Y86代码的唯一工具是汇编器。

--以“.”开头的词是汇编命令,他们告诉汇编器调整地址,以便在那儿产生代码或插入一些数据。命令.pos0告诉编译器应该从地址0处开始产生代码。这个地址是所有Y86程序的起点。

4.2 逻辑设计和硬件控制语言HCL

一、逻辑门

--逻辑门产生的输出,等于它们输入位值的某个布尔函数。

--AND &&

OR ||

NOT !

二、组合电路和布尔表达式

--逻辑门产生的输出,等于它们输入位值的某个布尔函数。

--两个或多个逻辑门的输出不能连接在一起,否则可能会使线上的信号矛盾,导致一个不合法的电压或电路故障。

--网必须无环。

三、字级的组合电路和HCL整数表达式

 

--所有字级的信号都声明为int,不指定字的大小

--算数/逻辑单元(ALU)是很重要的组合电路,有三个输入,标号为A、B的两个数据输入和一个控制输入。根据控制输入的设置,电路会对数据输入执行不同的算数或逻辑操作。

四、集合关系

--判断集合关系的通用格式是:iexpr in {iexpr1,iexpr2,...,iexprk}

五、存储器和时钟

--时钟寄存器(简称寄存器)存储单个位或字,时钟信号控制寄存器加载输入值

--随机访问存储器(简称存储器)存储多个字,用地址来选择该读或该写哪个字

4.3 Y86的顺序实现

一、将处理组织成阶段

 

--取指:取指阶段从存储器读取指令字节,地址为程序计数器PC的值

 

--译码:译码阶段从寄存器文件读入最多两个操作数

 

--执行:在执行阶段,算数/逻辑单元要么根据ifun的值执行指令指明的操作,计算机存储器引用的有效地址,要么增加或减少栈指针

 

--访存:访存阶段可以将数据写入存储器,或从存储器读出数据

 

--写回:写回阶段最多可以写两个结果到寄存器文件

 

--更新PC:将PC设置成下一条指令的地址

二、SEQ硬件结构和时序:看书上P258图

三、SEQ阶段的实现

--取指阶段:取指阶段包括指令存储器硬件单元。以PC作为第一个字节(字节0)的地址,这个单元一次从存储器读出6个字节,第一个字节被解释称指令字节,分为两个4位数。标号为“icode”和“ifun”的控制逻辑块计算指令和功能码等于从存储器读出值,或者当指令地址不合法时(imem_error指明),这些值对应于nop指令。

--译码和写回阶段:都要访问寄存器文件。寄存器文件有四个端口,支持同时进行两个读(端口A、B)和两个写(E、M),每个端口都有一个地址连接和一个数据连接。根据指令代码icode以及寄存器指示值rA和rB,可能还会根据执行阶段计算出的Cnd条件信号。

--执行阶段:执行阶段包括算术/逻辑单元(ALU)第一步每条指令的ALU计算,执行阶段还包括条件码寄存器。

--访存阶段:访存阶段的任务是读或者写程序数据,两个控制块产生存储器地址和存储器输入数据的值,另外两个块产生控制信号表明应该执行读操作还是写操作。当执行读操作时数据存储器产生值valM。

--更新PC阶段:SEQ中最后一个阶段会产生程序计数器的新值,依据指令的类型和是否要选择分支,新的PC可能是valC、valM、valP

 

第六周

三种常见存储技术:RAM/ROM/磁盘

(1)随机访问存储器RAM

  • 两类:静态RAM(SRAM)和动态RAM(DRAM)

  • 静态RAM(SRAM)比动态RAM(DRAM)更快,但也贵很多。

  • 静态RAM

    • SRAM将每个位存储在一个双稳态的存储器单元里,每个单元是用一个六晶体管电路来实现的。
    • 这个电路的一个属性:它可以无限制地保持在两个不同的电压配置或状态之一。其他任何状态都是不稳定的。

      - 特点:由于SRAM的双稳态特性,只要有电,它就会永远地保持它的值,即使有干扰,如电子噪音,来扰乱电压,当干扰消除,电路也能恢复到稳定值。
      - 应用:SRAM用来作为高速缓存存储器,即可以在CPU芯片上,也可以在片下。
  • 动态DRAM

    • DRAM将每个位存储为对电容的充电。电容约为30×10-15F。

      - 特点:对干扰特别敏感,当电容的电压被扰乱之后,它就永远不会恢复了。暴露在光线下会导致电容电压改变。
    • - FLASH:闪存,基于EEPROM。(固态硬盘SSD基于闪存)
      • 存储在ROM设备中的程序通常称为固件。

      (3)访问主存

      - 读事务:从主存传送数据到CPU。
      - 写事务:从CPU传送数据到主存。
      - 总线:一组并行的导线,能携带地址、数据的控制信号。
      	数据总线、控制总线、地址总线
      • 读事务语句

        movl A,%eax

        - CPU从总线读出字x,并将它copy到寄存器eax中。

      • 写事务语句
      • movl %eax,A

      (4)磁盘存储

      • 磁盘构造

        • 盘片构成,每个盘片有两面或者称为表面,表面覆盖着磁性记录材料。盘片中央有一个可以旋转的主轴,使得盘片以固定的旋转速率旋转,通常是5400~15000转每分钟(RPM)
        • 每个表面是由一组称为磁道的同心圆组成;每个磁道被划分成一组扇区;每个扇区包含相等数量的数据位(通常是512字节);这些数据编码在扇区上的磁性材料中。扇区之间由一些间隙分隔开,这些间隙中不存在数据位。间隙存储用来标识扇区的格式化位。

         

      • 磁盘容量

        • 一个磁盘上可以记录的最大位数称为它的最大容量/容量。
        • 磁盘容量的决定因素:

          - 记录密度:磁道一英寸的段可以放入的位数。
          - 磁道密度:从盘片中心出发半径上一英寸的段内可以有的磁道数。
          - 面密度:记录密度与磁道密度的乘积。

学习总结

 老师提高我的学习能力,传授了科学的学习方法,以改变我不良的学习思维习惯为出发点,我在上课后及时消化课上知识,学习到不要就题论题,要灵活运用老师所讲知识举一反三,触类旁通,尤其是对我这种学习成绩并不是特别优秀的学生,学习后应遵循“复习为主,少做精练”的原则。古语说得好,温故而知新,我绝不能忽视旧课复习,一味地关注下半学期新课的学习,应充分利用下课将上半学期旧课知识的疑点、难点、重点进行有效地查漏补缺。

 

posted @ 2015-11-01 18:39  20135326王亦可  阅读(242)  评论(1编辑  收藏  举报