按键 |
作用 |
Ctrl+d |
键盘输入结束或退出终端 |
Ctrl+s |
暂定当前程序,暂停后按下任意键恢复运行 |
Ctrl+z |
将当前程序放到后台运行,恢复到前台为命令fg |
Ctrl+a |
将光标移至输入行头,相当于Home键 |
Ctrl+e |
将光标移至输入行末,相当于End键 |
Ctrl+k |
删除从光标所在位置到行末 |
Alt+Backspace |
向前删除一个单词 |
Shift+PgUp |
将终端显示向上滚动 |
Shift+PgDn |
将终端显示向下滚动 |
Shell 常用通配符:
字符 |
含义 |
* |
匹配 0 或多个字符 |
? |
匹配任意一个字符 |
[list] |
匹配 list 中的任意单一字符 |
[!list] |
匹配 除list 中的任意单一字符以外的字符 |
[c1-c2] |
匹配 c1-c2 中的任意单一字符 如:[0-9] [a-z] |
{string1,string2,...} |
匹配 sring1 或 string2 (或更多)其一字符串 |
{c2..c2} |
匹配 c1-c2 中全部字符 如{1..10} |
who 命令其它常用参数
参数 |
说明 |
-a |
打印能打印的全部 |
-d |
打印死掉的进程 |
-m |
同am i,mom likes |
-q |
打印当前登录用户数及用户名 |
-u |
打印当前登录用户登录信息 |
-r |
打印运行等级 |
使用groups命令
查看/etc/group文件
删除用户
查看文件权限
我们之前已经很多次用到 ls 命令了,如你所见,我们用它来列出并显示当前目录下的文件,当然这是在不带任何参数的情况下,它能做的当然不止这么多,现在我们就要用它来查看文件权限。
变更文件所有者
vim基本操作
1.六种基本模式:
(1)普通模式(Normal mode)
(2)插入模式(Insert mode)
(3)可视模式(Visual mode)
(4)选择模式(Select mode)
(5)命令行模式(Command line mode)
(6)Ex模式(Ex mode)
2.常用命令总结
(1)插入
i 在当前光标处进行编辑
I 在行首插入
A 在行末插入
a 在光标后插入编辑
o 在当前行后插入一个新行
O 在当前行前插入一个新行
cw 替换从光标所在位置后到一个单词结尾的字符
(2)退出
:q! 强制退出,不保存
:q 退出
:wq! 强制保存并退出
:w <文件路径> 另存为
:saveas 文件路径 另存为
:x 保存并退出
:wq 保存并退出
(3)删除
x 删除游标所在的字符
X 删除游标所在前一个字符
Delete 同x
dd 删除整行
dw 删除一个单词(不适用中文)
d$或D 删除至行尾
d^ 删除至行首
dG 删除到文档结尾处
d1G 删至文档首部
(4)行间跳转
nG(n Shift+g) 游标移动到第 n 行
(如果默认没有显示行号,请先进入命令模式,输入:set nu以显示行号)
gg 游标移动到到第一行
G(Shift+g) 到最后一行
(5)行内跳转
w 到下一个单词的开头
e 到下一个单词的结尾
b 到前一个单词的开头
ge 到前一个单词的结尾
0或^ 到行头
$ 到行尾
f<字母> 向后搜索<字母>并跳转到第一个匹配的位置(非常实用)
F<字母> 向前搜索<字母>并跳转到第一个匹配的位置
t<字母> 向后搜索<字母>并跳转到第一个匹配位置之前的一个字母(不常用)
T<字母> 向前搜索<字母>并跳转到第一个匹配位置之后的一个字母(不常用)
(6)复制与粘贴
yy 复制游标所在的整行(3yy表示复制3行)
y^ 复制至行首,或y0。不含光标所在处字符。
y$ 复制至行尾。含光所在处字符。
yw 复制一个单词。
y2w 复制两个单词。
yG 复制至文本末。
y1G 复制至文本开头。
普通模式中使用p粘贴
p(小写) 代表粘贴至光标后(下)
P(大写) 代表粘贴至光标前(上)
(7)替换和撤销
r+<待替换字母> 将游标所在字母替换为指定字母
R 连续替换,直到按下Esc
cc 替换整行,即删除游标所在行,并进入插入模式
cw 替换一个单词,即删除一个单词,并进入插入模式
C(大写) 替换游标以后至行末
~ 反转游标所在字母大小写
u{n} 撤销一次或n次操作
U(大写) 撤销当前行的所有修改
Ctrl+r redo,即撤销undo的操作
(8)快速缩进与文本位置
>> 整行将向右缩进
<< 整行向左回退
:set shiftwidth? 获取目前的设定值
:set shiftwidth=10 设置缩进为10个字符
:ce 本行内容居中
:ri(right) 本行文本靠右
:le(left) 本行内容靠左
(9)查找
/icmp 查找字符串icmp
n 查找下一个icmp
?tcp 向上查找字符串tcp
N 查找上一个出现的tcp
\* 寻找游标所在处的单词
\# 同上,但\* 是向前(上)找,#则是向后(下)找
g\* 同\* ,但部分符合该单词即可
g\# 同\# ,但部分符合该单词即可
(10)多文件编辑
vim 1.txt 2.txt
:n 编辑2.txt文件,可以加!即:n!强制切换
:N 编辑1.txt文件,可以加!即:N!强制切换,
注:之前文件内的输入没有保存,仅仅是切换到另一个文件
进入vim后打开新文件
:e 3.txt 打开新文件3.txt
:e# 回到前一个文件
:ls 可以列出以前编辑过的文档
:b 2.txt(或编号) 可以直接进入文件2.txt编辑
:bd 2.txt(或编号) 可以删除以前编辑过的列表中的文件项目
:e! 4.txt 新打开文件4.txt,放弃正在编辑的文件
:f 显示正在编辑的文件名
:f new.txt 改变正在编辑的文件名字为new.txt
(11)视窗操作
:sp 1.txt 打开新的横向视窗来编辑1.txt
:vsp 2.txt 打开新的纵向视窗来编辑1.txt
Ctrl-w s 将当前窗口分割成两个水平的窗口
Ctrl-w v 将当前窗口分割成两个垂直的窗口
Ctrl-w q 即 :q 结束分割出来的视窗。如果在新视窗中有输入需要使用强制符!即:q!
Ctrl-w o 打开一个视窗并且隐藏之前的所有视窗
Ctrl-w j 移至下面视窗
Ctrl-w k 移至上面视窗
Ctrl-w h 移至左边视窗
Ctrl-w l 移至右边视窗
Ctrl-w J 将当前视窗移至下面
Ctrl-w K 将当前视窗移至上面
Ctrl-w H 将当前视窗移至左边
Ctrl-w L 将当前视窗移至右边
Ctrl-w 减小视窗的高度
Ctrl-w + 增加视窗的高度
(12)功能设定
:set或者:se 显示所有修改过的配置
:set all 显示所有的设定值
:set option? 显示option的设定值
:set nooption 取消当期设定值
:set autoindent(ai) 设置自动缩进
:set autowrite(aw) 设置自动存档,默认未打开
:set background=dark或light 设置背景风格
:set backup(bk) 设置自动备份,默认未打开
: set cindent(cin) 设置C语言风格缩进
(13)创建加密文档
$ vim -x file1
3.vimtutor练习教程实践
(1)文本简单操作
光标在屏幕文本中的移动既可以用箭头键,也可以使用 hjkl 字母键。
h (左移) j (下行) k (上行) l (右移)
欲进入vim编辑器(从命令行提示符),请输入∶vim 文件名 <回车>
欲退出vim编辑器输入以下命令放弃所有修改∶:q!<回车>
输入以下命令保存所有修改∶ :wq <回车>
在正常模式下删除光标所在位置的字符,请按∶ x
在光标所在位置开始插入文本,请按∶i 输入必要文本
(2)删除与撤销
欲从当前光标删除至单字/单词末尾,请输入∶dw
欲从当前光标删除至当前行末尾,请输入∶d$
欲删除整行,请输入∶dd
在正常模式下一个命令的格式是∶[number] command object 或 command [number] object
number - 代表的是命令执行的次数
command - 代表要做的事情,比如 d 代表删除
object - 代表要操作的对象,比如 w 代表单字/单词,$ 代表到行末等等。
欲撤消以前的操作,请输入∶u (小写的u)
欲撤消在一行中所做的改动,请输入∶U (大写的U)
欲撤消以前的撤消命令,恢复以前的操作结果,请输入∶CTRL-R
(3)置入、替换和更改
要重新置入已经删除的文本内容,请输入小写字母 p。该操作可以将已删除的文本内容置于光标之后。如果最后一次删除的是一个整行,那么该行将置于当前光标所在行的下一行。
要替换光标所在位置的字符,请输入小写的 r 和要替换掉原位置字符的新字符即可。
更改类命令允许您改变指定的对象,从当前光标所在位置直到对象的末尾。比如输入 cw 可以替换当前光标到单词的末尾的内容;输入 c$ 可以替换当前光标到行末的内容。
更改类命令的格式是∶
[number] c object 或者 c [number] object
(4)定位与搜索
Ctrl-g 用于显示当前光标所在位置和文件状态信息。Shift-G 用于将光标跳转至文件最后一行。先敲入一个行号然后按 Shift-G 则是将光标移动至该行号代表的行。
输入 / 然后紧随一个字符串是则是在当前所编辑的文档中向后查找该字符串。
输入问号 ? 然后紧随一个字符串是则是在当前所编辑的文档中向前查找该字符串。完成一次查找之后按 n 键则是重复上一次的命令,可在同一方向上查找下一个字符串所在;或者按 Shift-N 向相反方向查找下该字符串所在。
如果光标当前位置是括号(、)、[、]、{、},按 % 可以将光标移动到配对的
括号上。
在一行内替换头一个字符串 old 为新的字符串 new,请输入 :s/old/new
在一行内替换所有的字符串 old 为新的字符串 new,请输入 :s/old/new/g
在两行内替换所有的字符串 old 为新的字符串 new,请输入 :#,#s/old/new/g
在文件内替换所有的字符串 old 为新的字符串 new,请输入 :%s/old/new/g
进行全文替换时询问用户确认每个替换需添加 c 选项,请输入 :%s/old/new/gc
(5)外部命令与文件
:!command 用于执行一个外部命令 command。
例子∶
:!dir - 用于显示当前目录的内容。
:!rm FILENAME - 用于删除名为 FILENAME 的文件
:w FILENAME 可将当前 VIM 中正在编辑的文件保存到名为FILENAME 的文件中。
:#,#w FILENAME 可将当前编辑文件第 # 行至第 # 行的内容保存到文件FILENAME 中。
:r FILENAME 可提取磁盘文件 FILENAME 并将其插入到当前文件的光标位置后面。
(6)插入
输入小写的 o 可以在光标下方打开新的一行并将光标置于新开的行首,进入插入模式。
输入大写的 O 可以在光标上方打开新的一行并将光标置于新开的行首,进入插入模式。
输入小写的 a 可以在光标所在位置之后插入文本。
输入大写的 A 可以在光标所在行的行末之后插入文本。
输入大写的 R 将进入替换模式,直至按 键退出替换模式而进入正常模式。
输入 :set xxx 可以设置 xxx 选项。
(7)在线帮助
按下 键 (如果键盘上有的话)
按下 键 (如果键盘上有的话)
输入 :help <回车>
提供一个正确的参数给":help"命令,您可以找到关于该主题的帮助。
(8)vim功能
开始编辑vimrc文件,这取决于您所使用的操作系统∶
:edit ~/.vimrc 这是Unix系统所使用的命令
:edit $VIM/_vimrc 这是Windows系统所使用的命令
接着导入vimrc范例文件∶:read $VIMRUNTIME/vimrc_example.vim
保存文件,命令为∶:write
(9)宏录制
qa 操作序列 q, @a, @@
qa 把你的操作记录在寄存器 a。于是 @a 会replay被录制的宏。
@@ 是一个快捷键用来replay最新录制的宏。
(10)分屏
:split → 创建分屏 (:vsplit创建垂直分屏)
dir:dir就是方向,可以是 hjkl 或是 ←↓↑→ 中的一个,其用来切换分屏。
_ (或 |) : 最大化尺寸 (| 垂直分屏)
+ (或 -) : 增加尺寸
三、GCC编译器
1.gcc支持编译的一些源文件后缀名
.c C语言源文件
.C .cc .cxx C++源文件
.m Object-C源文件
.i 经过预处理后的C源文件
.ii 经过预处理后的C++源文件
.s .S 汇编语言源文件
.h 预处理文件(头文件)
.o 目标文件
.a 存档文件
2.gcc编译流程
原文件->预处理->编译->汇编->连接->可执行文件
预处理:gcc –E hello.c –o hello.i
注:请记住,gcc预处理源文件的时候(第一步),不会进行语法错误的检查。
语法检查会在第二步进行,比如花括号不匹配、行末尾没有分号、关键字错误等。
五、静态链接库与动态链接库
1.概念
通常情况下,对函数库的链接是放在编译时期(compile time)完成的。所有相关的对象文件(object file)与牵涉到的函数库(library)被链接合成一个可执行文件(executable file)。
静态链接库
动态链接库
2.创建与主程序运行
静态链接库
ar rcsv libxxx.a file1.o file2.o
./main
动态链接库
gcc -fPIC -c file2.c
gcc -shared -o libxxx.so file1.o file2.o
gcc -o main main.c -L. -lxxx
./main
3.编译参数
四、GDB调试技术
1.gdb主要功能
2.基本命令
(1)进入GDB
gcc -g test.c -o test
gdb test
(2)查看源码
(gdb) l
(3)设置断点
(gdb) b 6
(4)查看断点处情况
(gdb) info b
(5)运行代码
(gdb) r
(6)显示变量值
(gdb) p n
(7)观察变量
(gdb) watch n
(8)单步运行
(gdb) n
(9)程序继续运行
(gdb) c
(10)退出GDB
(gdb) q
3.四种断点
(1)函数断点
b 函数名 条件表达式
(2)行断点
b 行数或函数名 条件表达式
(3)条件断点
b 行数或函数名 if表达式
(4)临时断点
tbreak 行数或函数名 条件表达式
五、make与makefile
1.Makefile 介绍
make命令执行时,需要一个 Makefile 文件,以告诉make命令需要怎么样的去编译和链接程序。
1)如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。
2)如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。
3)如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。
2.Makefile的规则
target ... : prerequisites ...
command
...
...
这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则,也是Makefile中最核心的内容。
3.make工作方式
这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。make只管文件的依赖性,即如果在找了依赖关系之后,冒号后面的文件还是不在,那么就停止工作。
执行步骤:
(1)读入所有的Makefile。
(2)读入被include的其它Makefile。
(3)初始化文件中的变量。
(4)推导隐晦规则,并分析所有规则。
(5)为所有的目标文件创建依赖关系链。
(6)根据依赖关系,决定哪些目标要重新生成。
(7)执行生成命令。
4.带宏的 Makefile
(1)递归展开方式
VAR=var
(2)简单方式
VAR:=var
使用变量的格式为:
$(VAR)
5.自动变量
$* 和隐含规则匹配的stem(径),参阅格式匹配。如果一个目标为‘dir/a.foo.b',目标格式规则为:‘a.%.b' ,则stem为‘dir/foo'。在构建相关文件名时stem 十分有用。在静态格式规则中,stem是匹配目标格式中字符‘%’的文件名中那一部分。在一个没有stem具体规则中;变量‘$*' 不能以该方法设置。如果目标名以一种推荐的后缀结尾,变量‘$*'设置为目标去掉该后缀后的部分。例如,如果目标名是‘foo.c',则变量‘$*' 设置为‘foo', 因为‘.c' 是一个后缀。在隐含规则和静态格式规则以外,应该尽量避免使用变量‘$*'。在具体规则中如果目标名不以推荐的后缀结尾,则变量‘$*’在该规则中设置为空值。
三种重要的数字表示
(1)无符号数、有符号数、浮点数
(2)为什么用补码表示
如果把符号位单独考虑的话,CPU指令还要特意对最高位进行判断,使计算机的最底层实现变得复杂。
(3)整数溢出漏洞
参考资料:整数溢出与程序安全
有符号整数的另外两种标准表示方法
二进制反码形式:与二进制补码的表示方法类似,区别在于最高有效位的权值不同。
原码:最高有效位是符号位,确定剩下的位取负权值还是正权值。
符号数与无符号数之间的转换
ANSI C规定在无符号整数和有符号整数之间进行强制类型转换时,并未改变对象的位模式,改变的是位模式的解释方式。处理同样字长的有符号数和无符号数之间相互转换的一般规则是:数值可能会改变,位模式不变。
T2U:补码到无符号数的转换
U2T:无符号数到补码的转换
(*w表示数据类型的位数)
(*w表示数据类型的位数)
C中有符号和无符号数
隐式转换:一种类型的表达式被赋值给另外一种类型的变量时。
例:当一个有符号数“-1”与无符号数“0”用关系运算符连接时,会自动的将-1隐式转换为无符号数4294967295(假设是一个使用补码的32位机器),负数变成了正数,“-1<0u”的结果值就是0。
3.1历史观点
8086—〉80286—〉i386—〉i486—〉Pentium—〉PentiumPro—〉Pentium—〉Pentium—〉Pentium4—〉Pentium4e—〉Core 2 Duo —〉Core i7
3.2程序编码
1.gcc -01 –o p p1.c p2.c 使用第一级优化
2.程序计数器(%eip)指示将要执行的下一条指令在存储器中的地址。
3.寄存器文件
4.-S:C语言编译器产生的汇编代码
例:gcc -01 –S code.c 会产生一个汇编文件code.c
3.3数据格式
char |
字节 |
b |
1 |
short |
字 |
w |
2 |
int |
双字 |
1 |
4 |
long int |
双字 |
1 |
4 |
long long int |
— |
— |
4 |
char* |
双字 |
1 |
4 |
float |
单精度 |
s |
4 |
Double |
双精度 |
l |
8 |
long double |
扩展精度 |
t |
10/12 |
3.4访问信息
1.操作数指示符类型:立即数、寄存器、寄存器
2.数据传送指令
指令 |
效果 |
描述 |
MOV S,D |
S<-D |
传送 |
movb movw movl |
传送字节 传送字 传送双字 |
|
MOVS S,D |
D<-符号扩展(S) |
传送符号扩展的字节 |
MOVZ S,D |
D<-零扩展(S) |
传送零扩展的字节 |
3.5算术和逻辑操作(20135315韩玉琪的博客)
1.加载有效地址:leal实际上是movl的变形,为存储器引用产生指针
2.一元操作和二院操作:1)++,- -;2)+=
- NOT 取补
- AND 与
第二个操作数 操作符 第一个操作数
3.移位操作:>>,<<
- SHR 逻辑右移
4.特殊算术操作
- 从两个32位操作数产生一个32位的乘积。
- 乘积的高32位在%edx中,低32位在%eax中。
- 结果:商在AX中,余数在DX中。
- 通常会事先设定寄存器%edx为0.
3.6控制
1.条件码:
CF:进位标志 ZF:零标志 SF:符号标志 OF:溢出标志
2.访问条件码
3.跳转指令及其编码:jmp *%eax
4.条件传送指令(参考资料20135202闫佳歆博客)
(注:test-expr 整数表达式[假/真])
done:
5.switch语句
3.7过程
1.栈帧结构:机器用栈帧来传递过程参数、存储返回信息、保存寄存器用于以后的回复以及本地存储。为单个过程分配的那部分栈称为栈帧
2.帧指针:%ebp,栈指针:%%esp
3.转移控制
call Label 过程调用
call *Operand 过程调用
leave 为返回准备栈
ret 从过程调用中返回
4.寄存器使用惯例
1).%eax、%edx、%ecx 调用者保存
2).%ebx、%esi、%edi 被调用者保存
5.递归过程:递归调用一个函数本身与调用其他函数是一样的。相互调用更为复杂
问题:
1.比较指令cmp和减法指令sub有何不同?
sub d,s 是d-s,结果送回d中,即送回目的操作数中。
cmp d,s 也是d-s,但结果不送回目的操作数中,是利用减法进行两个数值的比较。
Y86指令集体系结构
定义一个指令集体系结构,包括定义各种状态元素、指令集和它们的编码、一组编程规范和异常事件处理。
程序员可见状态
Y86处理器状态类似于I32。可以访问和修改程序寄存器、条件码、程序计数器和存储器,状态码指明程序是否运行正常。
RF:程序寄存器 %eax,%ecx,%edx,%ebx,%esi,%edi,%esp(出栈、入栈、调用和返回指令作为栈指针),%ebp
CC:条件码 ZF、SF、OF(都是一位条件码,用来保存最近的算术或逻辑指令所造成影响的有关信息。)
PC:程序计数器 存放当前正在执行的指令
DMEM:存储器 很大的字节数组,保存着程序和数据。Y86程序用虚拟地址来引用存储器位置。
Stat:程序状态码 它表明程序执行的总体状态。它会指示是正常运行还是出现了某种异常。
Y86指令
IA32指令集的一个子集,只包括四字节整数操作。寻址方式比较少,操作也比较少。
IA32的movl指令分成了4个不同的指令:irmovl、rrmovl、mrmovl和rmmovl。分别显示地指明源和目的的格式。
源操作数: 立即数i、寄存器r、存储器m
目的操作数: 寄存器r、存储器m
两个存储器传送指令中的存储器引用方式是简单的基址和偏移量形式。
在地址计算中,不支持第二变址寄存器和任何寄存器值的伸缩。
不允许从一个存储器地址直接传送到另一个存储器地址。也不允许将立即数传送到存储器。
4个整数操作指令
addl、subl、andl、xorl
7个跳转指令(jXX)
jmp、jle、jl、je、jne、jge、jg
有6个条件传送指令(cmovXX)
cmovle、cmovl、cmove、cmovne、cmovge、cmovg
只有当条件码满足所需要的约束时,才会更新目的寄存器的值。
call指令将返回地址入栈,然后跳到目的地址。ret指令从这样的过程调用中返回。
pushl和popl指令实现了入栈和出栈。
halt指令停止指令的执行。对于Y86来说,执行halt指令会导致处理器停止,并将状态码设置为HLT。
指令编码
每条指令的第一个字节表明指令的类型。这个字节分为两个部分,每部分4位:高4位是代码部分,低4位是功能部分。功能值只有在一组相关指令共用一个代码时才有用。
整数操作里代码部分均为6,功能部分区分addl,subl,andl,xorl
分支指令里代码部分均为7
传送指令里代码部分均为2
8个程序寄存器中每个都有相应的0~7的寄存器标识符。
程序寄存器存在一个寄存器文件中,这个寄存器文件就是一个小的、以寄存器ID作为地址的随机访问存储器。当需要指明不应访问任何寄存器时,用ID值0xF表示。
没有寄存器操作数(分支指令和call指令),就没有寄存器指示符字节。
只需要一个寄存器操作数的指令(irmovl、pushl、popl),将另一个寄存器指示符设为0xF。
一个附加的4字节常数字,可作为:irmovl的立即数数据,rmmovl和mrmovl的地址指示符偏移量,分支指令和调用指令的目的地址。
注意:
分支指令和调用指令的目的地址是一个相对地址,而不是相对寻址方式。
所有整数采用小端法编码。当指令按反汇编格式书写时这些字节就以相反的顺序出现。
Y86异常
Y86状态码
出现异常时Y86处理器停止运行指令。可以调用一个异常处理程序使其更完整。
Y86程序
Y86代码与IA32代码的主要区别:
Y86可能需要多条指令来执行一条IA32指令所完成的功能。
Y86没有伸缩寻址模式。
命令指明应该将代码或数据放在什么位置,以及如何对齐。这个程序详细说明了栈的放置、数据初始化、程序初始化和程序结束等问题。
以“.”开头的词是汇编命令,他们告诉汇编器调整地址,以便在那儿产生代码或插入一些数据。
创建Y86代码的唯一工具是汇编器。
指令集模拟器YIS
二. 逻辑设计和硬件控制语言HCL
要实现一个数字系统需要三个主要的组成部分:
计算对位进行操作的函数的组合逻辑
存储位的存储器元素
控制存储器元素更新的时钟信号
逻辑门
AND &&
OR ||
NOT !
逻辑门只对单个位的数进行操作,而不是整个字。
组合电路和HCL布尔表达式
储器来存储程序数据。
处理器还包括另外一个只读存储器,用来读指令。
在大多数实际系统中,这两个存储器被合并为一个具有双端口的存储器:一个用来读指令,一个用来读或写数据。
Y86的顺序实现
SEQ 顺序处理器
每个时钟周期上,SEQ执行一条完整指令所需的所有步骤
六个基本阶段
- 取指 - 译码 - 执行 - 访存 - 写回 - 更新PC
SEQ
-SEQ抽象视图
程序计数器放在寄存器中
信息沿线流动
各个阶段相关的硬件单元负责执行这些处理
反馈线路包括要写到存储器文件的更新值,以及更新的程序计数器值
在SEQ中,所有硬件单元的处理都在一个时钟周期内完成
画图惯例
浅灰色方块表示硬件单元
控制逻辑块是用灰色圆角矩形表示的
线路的名字在白色椭圆中说明
宽度为字长的数据连接用中等粗度的线表示
宽度为字节或更窄的数据连接用细线表示
单个位的连接用虚线
SEQ的时序
SEQ的实现包括组合逻辑和两种存储器设备
时钟寄存器 程序计数器和条件码寄存器
随机访问存储器 寄存器文件、指令存储器和数据存储器
组合逻辑不需要任何时序或控制
由于指令存储器只用来读指令,我们可以将这个单元看成是组合逻辑
剩下四个(程序计数器、条件码寄存器、数据存储器和寄存器文件)需要对他们的时序进行明确的控制。
条件码寄存器 只在执行整数运算指令时装载
数据存储器 只在执行rmmovl、pushl或call时写入
寄存器文件 两个写端口允许每个时钟周期更新两个程序寄存器。(特殊寄存器ID 0xF表明此端口不应执行写操作)
组织计算原则
处理器从来不需要为了完成一条指令的执行而去读由该指令更新了的状态。
用时钟来控制状态元素的更新,值通过组合逻辑传播。
取指阶段
以PC为第一个字节的地址,一次读6个字节。
icode 控制逻辑块计算指令
ifun 功能码
三个一位的信号(根据icode值计算)
instr_valid 发现不合法的指令
need_regids 包含寄存器指示符字节吗
need_valC 包括常数字吗
后五个字节是寄存器指示符字节和常数字的组合编码。
译码和写回阶段
都需要访问寄存器文件,根据四个端口的情况,判断应该读哪个寄存器产生信号valA、valB。
寄存器文件,支持同时进行两个读和两个写,每个端口有一个地址连接(寄存器ID)和一个数据连接(32根线路),既可以作为寄存器文件的输出字,又可以作为他的输入字。
执行阶段
包括算数/逻辑单元(ALU),输出为valE信号。
ALU通常作为加法器使用
包括条件码寄存器
每次运行产生:
符号、溢出、产生信号set_cc
访存阶段
读或者写程序数据。
两个数据块产生存储器地址和存储器输入证据的值,两个产生控制信号表明应该是读还是写。当执行读操作时,数据存储器产生valM。
根据icode,imem_error,instr_valid,dmem_error,从指令执行的结果计算状态码Stat。
更新PC阶段
产生程序计数器的新值,依据指令的类型和是否要选择分支,新的PC可能是valC、valM或者valP。
存储器系统是一个线性的字节数组。是一个具有不同容量、成本和访问时间的存储设备的层次结构。
分类:1.靠近CPU的高速缓存存储器; 2.相对慢速的主存储器
存储器层次结构:指令制定期间——0周期;
高速缓存中——1-30个周期;
主存中——50-200个周期;
磁盘上——几千万个周期。
基本属性——局部性:多次访问相同数据项集合。
存储技术:1.SRAM存储器
2.DRAM存储器
3.ROM存储器
4.旋转的个固态的硬盘
6.1 存储技术
分类:静态(SRAM)——双稳态的(摆钟的左右两边状态)
动态(DRAM)——对干扰敏感
传统DRAM——分成d个超单元
存储器模块:1.双列(DIMM) 2.单列(SIMM)
增强的DRAM:快页模式
扩展数据输出
双倍数据速率通过不
非易失性存储器
访问主存——总线事务、读事务、写事务
盘片:表面*2+磁道+扇区(512bety)+间隙+主轴
旋转速率(5400-15000r/min)
容量=字节数*平均扇区数*磁道数*表面数*盘片数
扇区的访问时间=寻道时间+旋转时间+传送时间
6.2 局部性
6.3 存储器层次结构
缓存不命中种类:1).强制性不命中(冷缓存)——放置策略
2).冲突不命中
6.4 高速缓存存储器
L1高速缓存:位于CPU寄存器文件和主存之间,访问速度2-4个时钟周期
L2高速缓存:位于L1高速缓存和主存之间,访问速度10个时钟周期
L3高速缓存:位于L2高速缓存和主存之间,访问速度30或40个时钟周期
1. 通用的高速缓存存储器结构
m:每个存储器地址有m位,形成M=2^m个不同的地址
S:这个数组中有S=2^s个高速缓存组
E:每个组包含E个高速缓存行
B:每个行是由一个B=2^b字节的数据块组成的