diff --git a/.gitignore b/.gitignore index af389d4..ad89a41 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ -/imgs -/html \ No newline at end of file +/markdown/imgs +/markdown/html +node_modules +/.idea/ +/docs/.vuepress/dist/ diff --git a/README.md b/README.md index 31f2ef5..7918d9f 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,11 @@ ## changelog: + +2023年1月29日:vuepress驱动,大幅提升阅读和查询体验。 + +--- + 2022年1月10日:重新用nginx完成了部署,现在所有域名都可通过note.peteralbus.com访问 --- diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js new file mode 100644 index 0000000..594d6a3 --- /dev/null +++ b/docs/.vuepress/config.js @@ -0,0 +1,26 @@ +module.exports = { + title: 'PeterAlbus的笔记本', + description: '大学期间相关课程的知识点汇总和复习资料', + themeConfig: { + nav: [ + { text: '主页', link: '/' }, + { text: '操作系统', link: '/ComputerOS.md' }, + { text: '计算机组成原理', link: '/ComputerOrganization.md' }, + { text: '计算机网络', link: '/ComputerNetwork.md' }, + { + text: '其他', + ariaLabel: '其余笔记链接', + items: [ + { text: '软件工程', link: '/SoftwareEngineering.md' }, + { text: '数据库', link: '/Database.md' }, + { text: '算法基础', link: '/FundamentalsOfAlgorithmics.md' }, + { text: '数学建模', link: '/MathematicalModeling.md' }, + { text: '汇编', link: '/AssemblyLanguage.md' } + ] + }, + { text: 'Github', link: 'https://github.com/PeterAlbus/PeterAlbusNotes' }, + ], + sidebarDepth: 2, + sidebar: 'auto' + } + } \ No newline at end of file diff --git a/docs/.vuepress/styles/index.styl b/docs/.vuepress/styles/index.styl new file mode 100644 index 0000000..0c724c6 --- /dev/null +++ b/docs/.vuepress/styles/index.styl @@ -0,0 +1,483 @@ +:root { + --side-bar-bg-color: #fff; + --control-text-color: #777; + --font-sans-serif: 'Ubuntu', 'Source Sans Pro', sans-serif !important; + --font-monospace: 'Fira Code', 'Roboto Mono', monospace !important; +} + +html { + font-size: 16px; +} + +body { + font-family: var(--font-sans-serif); + color: #34495e; + -webkit-font-smoothing: antialiased; + line-height: 1.6rem; + letter-spacing: 0; + margin: 0; + overflow-x: hidden; +} + +#write { + max-width: 860px; + margin: 0 auto; + padding: 20px 30px 100px; +} + +#write p { + line-height: 1.6rem; + word-spacing: .05rem; +} + +#write ol li { + padding-left: 0.5rem; +} + +#write > ul:first-child, +#write > ol:first-child { + margin-top: 30px; +} + +body > *:first-child { + margin-top: 0 !important; +} + +body > *:last-child { + margin-bottom: 0 !important; +} + +a { + color: #42b983; + font-weight: 600; + padding: 0 2px; + text-decoration: none; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + position: relative; + margin-top: 1rem; + margin-bottom: 1rem; + font-weight: bold; + line-height: 1.4; + cursor: text; +} + +h1:hover a.anchor, +h2:hover a.anchor, +h3:hover a.anchor, +h4:hover a.anchor, +h5:hover a.anchor, +h6:hover a.anchor { + text-decoration: none; +} + +h1 tt, +h1 code { + font-size: inherit !important; +} + +h2 tt, +h2 code { + font-size: inherit !important; +} + +h3 tt, +h3 code { + font-size: inherit !important; +} + +h4 tt, +h4 code { + font-size: inherit !important; +} + +h5 tt, +h5 code { + font-size: inherit !important; +} + +h6 tt, +h6 code { + font-size: inherit !important; +} + +h2 a, +h3 a { + color: #34495e; +} + +h1 { + padding-bottom: .4rem; + font-size: 2.2rem; + line-height: 1.3; +} + +h2 { + font-size: 1.75rem; + line-height: 1.225; + margin: 35px 0 15px; + padding-bottom: 0.5em; + border-bottom: 1px solid #ddd; +} + +h3 { + font-size: 1.4rem; + line-height: 1.43; + margin: 20px 0 7px; +} + +h4 { + font-size: 1.2rem; +} + +h5 { + font-size: 1rem; +} + +h6 { + font-size: 1rem; + color: #777; +} + +p, +blockquote, +ul, +ol, +dl, +table { + margin: 0.8em 0; +} + +li > ol, +li > ul { + margin: 0 0; +} + +hr { + height: 2px; + padding: 0; + margin: 16px 0; + background-color: #e7e7e7; + border: 0 none; + overflow: hidden; + box-sizing: content-box; +} + +body > h2:first-child { + margin-top: 0; + padding-top: 0; +} + +body > h1:first-child { + margin-top: 0; + padding-top: 0; +} + +body > h1:first-child + h2 { + margin-top: 0; + padding-top: 0; +} + +body > h3:first-child, +body > h4:first-child, +body > h5:first-child, +body > h6:first-child { + margin-top: 0; + padding-top: 0; +} + +a:first-child h1, +a:first-child h2, +a:first-child h3, +a:first-child h4, +a:first-child h5, +a:first-child h6 { + margin-top: 0; + padding-top: 0; +} + +h1 p, +h2 p, +h3 p, +h4 p, +h5 p, +h6 p { + margin-top: 0; +} + +li p.first { + display: inline-block; +} + +ul, +ol { + padding-left: 30px; +} + +ul:first-child, +ol:first-child { + margin-top: 0; +} + +ul:last-child, +ol:last-child { + margin-bottom: 0; +} + +blockquote { + border-left: 4px solid #42b983; + padding: 10px 15px; + color: #777; + background-color: rgba(66, 185, 131, .1); +} + +table { + padding: 0; + word-break: initial; +} + +table tr { + border-top: 1px solid #dfe2e5; + margin: 0; + padding: 0; +} + +table tr:nth-child(2n), +thead { + background-color: #fafafa; +} + +table tr th { + font-weight: bold; + border: 1px solid #dfe2e5; + border-bottom: 0; + text-align: left; + margin: 0; + padding: 6px 13px; +} + +table tr td { + border: 1px solid #dfe2e5; + text-align: left; + margin: 0; + padding: 6px 13px; +} + +table tr th:first-child, +table tr td:first-child { + margin-top: 0; +} + +table tr th:last-child, +table tr td:last-child { + margin-bottom: 0; +} + +#write strong { + padding: 0 1px; +} + +#write em { + padding: 0 5px 0 2px; +} + +#write table thead th { + background-color: #f2f2f2; +} + +#write .CodeMirror-gutters { + border-right: none; +} + +#write .md-fences { + border: 1px solid #F4F4F4; + -webkit-font-smoothing: initial; + margin: 0.8rem 0 !important; + padding: 0.3rem 0 !important; + line-height: 1.43rem; + background-color: #F8F8F8 !important; + border-radius: 2px; + font-family: var(--font-monospace); + font-size: 0.85rem; + word-wrap: normal; +} + +#write .CodeMirror-wrap .CodeMirror-code pre { + padding-left: 12px; +} + +#write code, tt { + padding: 2px 4px; + border-radius: 2px; + font-family: var(--font-monospace); + font-size: 0.92rem; + color: #e96900; + background-color: #f8f8f8; +} + +tt { + margin: 0 2px; +} + +#write .md-footnote { + background-color: #f8f8f8; + color: #e96900; +} + +/* heighlight. */ +#write mark { + background-color: #EBFFEB; + border-radius: 2px; + padding: 2px 4px; + margin: 0 2px; + color: #222; + font-weight: 500; +} + +#write del { + padding: 1px 2px; +} + +.cm-s-inner .cm-link, +.cm-s-inner.cm-link { + color: #22a2c9; +} + +.cm-s-inner .cm-string { + color: #22a2c9; +} + +.md-task-list-item > input { + margin-left: -1.3em; +} + +@media print { + html { + font-size: 13px; + } + + table, + pre { + page-break-inside: avoid; + } + + pre { + word-wrap: break-word; + } +} + +.md-fences { + background-color: #f8f8f8; +} + +.md-diagram-panel { + position: static !important; +} + +#write pre.md-meta-block { + padding: 1rem; + font-size: 85%; + line-height: 1.45; + background-color: #f7f7f7; + border: 0; + border-radius: 3px; + color: #777777; + margin-top: 0 !important; +} + +.mathjax-block > .code-tooltip { + bottom: .375rem; +} + +#write > h3.md-focus:before { + left: -1.5625rem; + top: .375rem; +} + +#write > h4.md-focus:before { + left: -1.5625rem; + top: .285714286rem; +} + +#write > h5.md-focus:before { + left: -1.5625rem; + top: .285714286rem; +} + +#write > h6.md-focus:before { + left: -1.5625rem; + top: .285714286rem; +} + +.md-image > .md-meta { + border-radius: 3px; + font-family: var(--font-monospace); + padding: 2px 0 0 4px; + font-size: 0.9em; + color: inherit; +} + +.md-tag { + color: inherit; +} + +.md-toc { + margin-top: 20px; + padding-bottom: 20px; +} + +.sidebar-tabs { + border-bottom: none; +} + +#typora-quick-open { + border: 1px solid #ddd; + background-color: #f8f8f8; +} + +#typora-quick-open-item { + background-color: #FAFAFA; + border-color: #FEFEFE #e5e5e5 #e5e5e5 #eee; + border-style: solid; + border-width: 1px; +} + +#md-notification:before { + top: 10px; +} + +/** focus mode */ + +.on-focus-mode blockquote { + border-left-color: rgba(85, 85, 85, 0.12); +} + +header, +.context-menu, +.megamenu-content, +footer { + font-family: var(--font-sans-serif); +} + +.file-node-content:hover .file-node-icon, +.file-node-content:hover .file-node-open-state { + visibility: visible; +} + +.mac-seamless-mode #typora-sidebar { + background-color: var(--side-bar-bg-color); +} + +.md-lang { + color: #b4654d; +} + +.html-for-mac .context-menu { + --item-hover-bg-color: #E6F0FE; +} diff --git a/docs/Advanced Mathematics.md b/docs/Advanced Mathematics.md new file mode 100644 index 0000000..399b479 --- /dev/null +++ b/docs/Advanced Mathematics.md @@ -0,0 +1,417 @@ +# 高等数学 + +### 第一章 函数与极限 + +#### 1.1 映射与函数 + +##### 1.1.1 映射 + +映射,用于引出函数的概念。 + +> 映射: $X、Y$为非空集合,法则$f$,对$X$中每个元素$x$都有**唯一**的$y$与之对应,则$f$被称作映射,$f$是$X\rarr Y$的一个映射。 +> +> $y$称作像,对应的$x$称作原像。 +> +> $X$叫定义域,记作$D_f$(Domain),$Y$叫做值域,记作$R_f$() + ++ 映射的三要素:$X、f、R_f$ + ++ $x \in X$,对应的$y$是唯一的 + + $R_f \subset Y$,两者不一定相同 + ++ 满射:$R_f = Y$,单射:当$x$不同时,对应的$y$也不同 + ++ 一一映射:同时满足单射和满射 + +复合映射:第二个映射的定义域包含第一个映射的值域。 + +##### 1.1.2 函数 + +1. 函数的概念 + +> **函数**是从数集到数集的映射。 +> +> 自变量、因变量、定义域、值域。 + +函数的表示方法: + +1. 表格 +2. 图形 +3. 解析式 + +一些函数的例子: + ++ 绝对值函数 ++ 符号函数 ++ 取整函数 + +2. 函数的特性 + + 1. 函数的有界性 + + 函数的有界性指函数分为有界函数和无界函数。 + + 通俗的讲,如果存在一个实数,使得值域内所有数都小于该数,同时存在一个实数,使得值域内所有数都大于该数。则该函数为有界函数。 + + 2. 函数的单调性 + + 函数的单调性指函数分为单调函数和非单调函数,单调函数又分为单调递增和单调递减。 + + 如果随着$x$值的增加,$f(x)$始终随之增加,则函数为单调递增。反之,函数为单调递减。 + + 同一个函数在不同区间上的单调性也可能不同。 + + 3. 函数的奇偶性 + + 判断函数的奇偶性时,函数的定义域$D$必须关于原点对称 + + 如果对于任意$x \in D$,$f(-x)=f(x)$,则函数为偶函数(函数图像关于y轴对称) + + 如果对于任意$x \in D$,$f(-x)=-f(x)$,则函数为奇函数(函数图像关于原点对称) + + 其他函数既不是奇函数也不是偶函数。 + + 4. 函数的周期性 + + > 设函数$f(x)$的定义域为$D$,如果存在一个正数$l$,使得对于任意$x\in D$有$(x+l)\in D$,且: + > $$ + > f(x \pm l)=f(x) + > $$ + > 恒成立,则称$f(x)$为**周期函数**,$l$称为$f(x)$的**周期**,通常我们说的周期函数的周期是指**最小正周期**。 + + 通俗来说,周期性指函数在定义域内周期性变换的特性。 + +3. 反函数与复合函数 + + **反函数是逆映射的一种特例。** + + 通俗来说,如果对于函数中的每个$y$值有唯一的$x$使得$f(x)=y$,则存在反函数使得: + $$ + f^{-1}(y)=x + $$ + 相对于反函数,原来的函数被称为**直接函数** + + 反函数和直接函数的图形关于直线$y=x$对称 + + **复合函数则是复合映射的一种特例。** + + > 设函数$y=f(x)$的定义域为$D_f$,函数$u=g(x)$的定义域为$D_g$,且值域$R_g \in D_f$,则由下式确定的函数: + > $$ + > y=f[g(x)],x\in D_g + > $$ + > 称为函数$u=g(x)$与函数$y=f(x)$构成的复合函数,变量$u$称为中间变量。 + + 两者以先g后f的次序复合的函数,通常记作$f \circ g$。$(f \circ g)(x)=f[g(x)]$ + + 构成复合函数$f \circ g$的条件是函数$g$的值域必须包含于函数$f$的定义域。 + + 如果限制函数$g$的定义域,使得其值域包含于函数$f$的定义域,这之后两者可组成复合函数。 + +4. 函数的运算 + + > 设函数$f(x),g(x)$的定义域依次为$D_f,D_g D=D_f \cap D_g \neq \emptyset$ + > + > 和/差:$(f\pm g)(x)=f(x)\pm g(x),x\in D$ + > + > 积:$(f \cdot g)(x)=f(x)\cdot g(x),x\in D$ + > + > 商:$(\frac f g)(x)=\frac{f(x)}{g(x)},x\in d / \{ x\mid g(x)=0,x\in D \}$ + +5. 初等函数 + + 五类基本初等函数: + + + 幂函数 + + 指数函数 + + 对数函数 + + 三角函数 + + 反三角函数 + + 由以上五类基本初等函数经过有限次四则运算和函数复合形成的函数都是初等函数。(课程讨论的基本都是初等函数) + +#### 1.2 数列的极限 + +1. 数列极限的定义 + +> 如果按照某一法则,对每个$n \in N$,对应着一个确定的实数$x_n$,这些实数$x_n$按照下标$n$从小到达排列得到的一个数列: +> $$ +> x_1,x_2,x_3,...,x_n,... +> $$ +> 就叫做**数列**,简记为数列$\{x_n\}$ + +数列中每个数叫做数列的项,第$n$项$x_n$叫做数列的**一般项**(或**通项**) + +例如,数列: +$$ +\frac 1 2,\frac 2 3,\frac 3 4,...,\frac {n}{n+1},... +$$ +的一般项/通项为$\frac {n}{n+1}$ + +**数列极限**讨论的问题则是,当$n$无限增大时(即$n \rightarrow \infin$时),对应的$x_n$是否能无限接近某个确定的数值。如果能,这个数值为多少。 + +一般的,有如下数列极限的定义: + +> 设$\{x_n\}$为一数列,如果存在常数$a$,对于任意给定的正数$\epsilon$(不论它多么小),总存在正整数$N$,使得当$n>N$时,不等式 +> $$ +> \mid x_n-a\mid<\epsilon +> $$ +> 都成立,那么就称常数$a$是数列$\{x_n\}$的**极限**,或者称数列**收敛**于$a$。 + +通俗来讲,数列的极限指数列无限接近的值。 + +2. 收敛数列的性质 + +定理1 极限的唯一性:如果数列${x_n}$收敛,那么它的极限唯一 + +定理2 收敛数列的有界性:如果数列收敛,那么数列一定有界 + +定理3 收敛数列的保号性:如果$\lim_{x \to +\infty} x_n=a$且$a>0(或a<0)$,那么存在正整数$N$,当$n>N$时,都有$x_n>0$ + +定理4 收敛数列与其子数列间的关系 如果数列$\{x_n\}$收敛与$a$,那么它的任一字数列也收敛,且极限也是$a$ + +#### 1.3 函数的极限 + +##### 1.3.1 函数极限的定义 + +数列$\{x_n\}$可以看作自变量为$n$的函数,数列的极限$a$就是当函数的自变量$n$取正整数而无限增大时,对应的函数$f(n)$无限接近的数$a$。 + +通过数列的极限,可以引出函数极限的一般概念: + +> 在自变量的某个变化过程中,如果对应的函数值无限接近于某个确定的数,那么这个确定的数就叫做在这一变化过程中**函数的极限**。 + +数列的极限看作函数$f(n)$当$n \to \infin$时的极限。 + +自变量的变化过程为其他情形时研究函数的极限,主要研究两种情形: + ++ 自变量任意的接近于有限值$x_0$ ++ 自变量$x$的绝对值无限增大即区域无穷大 + +1. 自变量趋于有限值时函数的极限 + + 设函数$f(x)$在点$x_0$的某一去心邻域内有定义,如果存在常数$A$,对于任意给定的正数$\epsilon$,无论它多么小,总存在正数$\delta$,使得当$x$满足不等式$0<\mid x-x_0 \mid < \delta$时,对应的函数值$f(x)$都满足不等式: + $$ + \mid f(x) - A \mid < \epsilon + $$ + 那么常数$A$就叫做函数$f(x)$当$x \to x_0$时的极限。记作 + $$ + \lim _{x \to x_0}f(x)=A + $$ + $x \to x_0$时函数有没有极限,与函数在$x_0$有无定义并无关系。 + + 当仅考虑$x$从$x_0$的左侧或右侧趋于$x_0$的情形时,得到的极限被叫做左极限/右极限。两者统称单侧极限。 + + 函数的极限存在的充分必要条件是左极限和右极限各自存在并且相等。 + +2. 自变量区域无穷大时函数的极限 + + 设函数$f(x)$当$\mid x \mid$大于某一正数时有定义,如果存在常数A,对于任意给定的正数$\epsilon$,无论它多小,总存在正数$X$,使得当$x$满足不等式$\mid x \mid >X$时,对应的函数值$f(x)$都满足不等式: + $$ + \mid f(x)-A \mid < \epsilon + $$ + 那么常数$A$就叫做函数$f(x)$当$x \to \infty$时的极限,记作 + $$ + \lim _{x \to + \infin} = A + $$ + +##### 1.3.2 函数极限的性质 + ++ 定理1 函数极限的唯一性 如果$\lim _{x \to x_0} f(x)$存在,那么这极限唯一 ++ 定理2 函数极限的局部有界性 通俗地讲,函数极限周围的值总在一个范围内 ++ 定理3 函数极限的局部保号性 通俗地讲,函数极限周围一定范围内,符号不变 ++ 定理4 函数极限与数列极限的关系 函数极限$\lim _{x \to x_0}f(x)$存在,如果数列为函数的定义域内任意收敛于$x_0$的数列,且$x_n \neq x_0$,那么相应的函数值数列$\mid f(x_n) \mid$必收敛 + +#### 1.4 无穷小与无穷大 + +##### 1.4.1 无穷小 + +> 如果函数$f(x)$当$x \to x_0(或\infin)$时极限为零,那么称$f(x)$为当$x \to x_0(或\infin)$时的无穷小。 + +##### 1.4.2 无穷大 + +通俗来说,如果函数在某一去心邻域内有定义,对于任意给定的正数,无论它多么大,总存在一个在去心邻域旁的定义域区间,其中的函数值都能大于给定的正数。这时称函数趋近于该中心的无穷大。 + +#### 1.5 极限运算法则 + +**定理1 两个无穷小的和是无穷小** + +详细证明过程略。通俗来说,如果a和b都是当$x \to x_0$的无穷小。任取一个大于0的数字,对于a和b,都能找到一个数字,使得a和b与$x_0$的距离小于那个值时,小于那个数字的1/2,则a和b相加 小于那个数字,符合无穷小的定义,故定理成立。 + +有限个无穷小之和也是无穷小。 + +**定理2 有界函数与无穷小的乘积是无穷小** + +严谨证明过程略。通俗来说,由于有界函数在某一去心邻域内值域总在一个实数范围内,而对于一个是无穷小的函数来说,任取一个大于0的数字,无论这个数字除以多么大的一个实数,总能找到一个函数小于这个值的范围。因此这个函数与这个有界函数相乘,也满足无穷小的定义,故定理成立。 + +**推论1 常数与无穷小的乘积是无穷小** + +**推论2 有限个无穷小的乘积是无穷小** + +**定理3 如果$\lim f(x)=A, \lim g(x)=B$.那么:** + +1. $\lim[f(x) \pm g(x)]=\lim f(x) \pm \lim g(x)=A \pm B$ + +2. $\lim[f(x) \cdot g(x)]=\lim f(x) \cdot \lim g(x)=A \cdot B$ + +3. 若又有$B \neq 0$: + $$ + \lim \frac {f(x)}{g(x)}= \frac {\lim f(x)}{\lim g(x)}=\frac A B + $$ + +**推论1 如果$\lim f(x)$存在,而$c$为常数,那么$\lim (cf(x))=c \lim f(x)$** + +**推论2 如果$\lim f(x)$存在,而$x$为正整数,那么$lim [f(x)]^n = [lim f(x)]^n$** + +**定理4 设有数列$\mid x_n \mid$和$\mid y_n \mid$,极限为$A$和$B$:** + +1. $\lim _{n \to \infin} (x_n \pm y_n) =A \pm B$ +2. $\lim _{n \to \infin} (x_n \cdot y_n) =A \cdot B$ +3. $y_n \neq 0$且$B \neq 0$时,$\lim _{n \to \infin} \frac{x_n}{y_n}=\frac AB$ + +**定理5 如果$f(x)\ge g(x)$,那么$\lim f(x) \ge \lim g(x)$** + +定理6 复合函数的极限运算法则: + +设$\lim_{x \to x_0} g(x)=u_0$,$\lim_{x \to u_0} f(x)=A$,则$\lim _ {x \to x0} f[g(x)]=\lim _ {u \to u0} f(u)=A$ + +#### 1.6 极限存在准则 + +**准则1 :如果数列$x_n,y_n,z_n$满足以下条件** + ++ 从某项起,即$\exists n_0 \in N$,当$n>n_0$时,有$y_n \le x_n \le z_n$ ++ $\lim_{n \to \infin} y_n =A,\lim_{n \to \infin} z_n =A$ + +那么数列$x_n$的极限存在,且$\lim_{n \to \infin} x_n=A$ + +准则推广到函数上同样成立,该准则称为夹逼准则。 + +**准则2:单调有界数列必有极限** + +当函数的左邻域内单调且有界,那么左极限必定存在。 + +柯西极限存在准则:数列极限的充要条件,任取一个正数,无论它多么小,存在一项,在这之后任意两项之间的距离都小于改正数。 + +#### 1.7 无穷小的比较 + +无穷小的和、差、积仍是无穷小,但无穷小的商会出现不同的情况,这反映了不同的无穷小趋于0的快慢。如: +$$ +\lim_{x \to 0} \frac{x^2}{3x}=0,\lim_{x \to 0} \frac{3x}{x^2}=\infin,\lim_{x \to 0} \frac{\sin 3x}{3x}=\frac 13 +$$ +**定义**: + +如果$\lim \frac{\beta}{\alpha}=0$,那么就说$\beta$是比$\alpha$高阶的无穷小。 + +如果$\lim \frac{\beta}{\alpha}=\infin$,那么就说$\beta$是比$\alpha$低阶的无穷小。 + +如果$\lim \frac{\beta}{\alpha}=c \ne 0$,那么就说$\beta$是$\alpha$同阶的无穷小。 + +如果$\lim \frac{\beta}{\alpha^k}=c \ne 0$,那么就说$\beta$是管局$\alpha$的k阶的无穷小。 + +如果$\lim \frac{\beta}{\alpha}=1$,那么就说$\beta$与$\alpha$等阶无穷小,记作$\alpha \sim \beta$。(是同阶无穷小的特殊情形) + +**定理1 $\beta$与$\alpha$是等价无穷小的充分必要条件是$\beta=\alpha+o(\alpha)$** + +**定理2 求两个等价无穷小之比的极限时,分子和分母都可以用等价无穷小代替。** + +#### 1.8 函数的连续性与间断点 + +##### 1.8.1 函数的连续性 + +气温变动等连续性变化,反映到函数上,就被称为函数的连续性。 + +> 定义:设函数$y=f(x)$在点$x_0$的某一邻域内有定义,如果: +> $$ +> \lim_{\Delta x \to 0} \Delta y=\lim_{\Delta x \to 0} [f(x_0+\Delta x)-f(x_0)]=0 +> $$ +> 或 +> $$ +> \lim_{x \to x_0}f(x)=f(x_0) +> $$ +> +> +> 那么就称函数$y=f(x)$在$x$点连续。 + +连续性还分为左连续和右连续。 + +在区间上每一点都连续的函数,叫做该区间上的连续函数。 + +##### 1.8.2 函数的间断点 + +设函数$f(x)$在点$x_0$的某去心邻域内有定义,如果在下列三种情况之一: + +1. 在$x=x_0$没有定义 +2. 在$x=x_0$有定义,但$\lim_{x \to x_0}f(x)$不存在 +3. 在$x=x_0$有定义,$\lim_{x \to x_0}f(x)$存在,但$\lim_{x \to x_0}f(x) \ne f(x_0)$ + +那么函数$f(x)$在$x_0$不连续,点$x_0$称为$f(x)$的不连续点或间断点。 + +常见类型: + ++ 无穷间断点 ++ 震荡间断点 ++ 可去间断点 ++ 跳跃间断点 + +如果间断点处左极限和右极限都存在,那么称之为第一类间断点,反之为第二类间断点。 + +#### 1.9 连续函数的运算与初等函数的连续性 + +##### 1.9.1 连续函数的和、差、积、商的连续性 + +**定理1 设函数$f(x)$和$g(x)$在点$x_0$处连续,则它们的和、差、积、商都在点$x_0$处连续。** + +##### 1.9.2 反函数与复合函数的连续性 + +**定理2 如果函数在区间上单调递增(递减),那么它的反函数在对应的区间上也呈单调递增/递减** + +**定理3 设函数$y=f[g(x)]$由函数$u=g(x)$与函数$y=f(u)$复合而成,$x_0$的去心邻域在函数的定义域内,若$\lim_{x \to x_0}g(x)=u_0$,而函数$y=f(u)$在$u=u_0$处连续,则:** +$$ +\lim_{x \to x_0}f[g(x)]=\lim_{u \to u_0}f(u)=f(u_0) +$$ +**定理4 复合函数$f \circ g$中,若$g$在$x_0$连续,且$g$在$x_0$的值对于$f$在这个位置也连续,则复合函数也连续。** + +##### 1.9.3 初等函数的连续性 + +基本初等函数在它们的定义域内都是连续的。 + +由本章的定理又可得,初等函数在他们的定义区间内都是连续的。 + +#### 1.10 闭区间上连续函数的性质 + +**定理1 在闭区间上连续的函数在该区间上有界且一定能取得它的最大最小值** + +**定理2(零点定理) 设$f(x)$在闭区间$[a,b]$上连续,且$f(a)$与$f(b)$异号,则开区间内必有一点函数值为0** + +**定理3(介值定理)设$f(x)$在闭区间$[a,b]$上连续,且$f(a)=A$,$f(b)=B$,则对于A和B之间的任意一个数c,在开区间$(a,b)$内必有一点$c$使得$**f(c)=C$ + +#### 常见题型及思路 + ++ 函数和函数是否相同:定义域相同、表达关系相同 ++ 求单调性:任取$x_1,x_2$,按定义找。或求导。 ++ 奇偶性\偶函数:$f(-x)$。 + +### 第二章 导数与微分 + +#### 2.1 导数概念 + +> 导数表示函数在某一点上的变化率。 + +定义式: +$$ +y{'}=\lim_{\Delta x \rarr 0} \frac {f(x+ \Delta x)-f(x)}{\Delta x} +$$ +几何意义:切线方程的斜率 + +函数在点x初连续是函数在点x处可导的**必要条件**,但不是**充分条件**。 + +#### 2.2 导数运算法则 + ++ $[u(x) \pm v(x)]^{'}=u^{'}(x) \pm v^{'}(x)$ ++ $[u(x)v(x)]^{'}=u^{'}(x)v(x)+u(x)v^{'}(x)$ ++ $[\frac {u(x)}{v(x)}]^{'}=\frac {u^{'}(x)v(x)-u(x)v^{'}(x)}{v^2(x)} (v(x) \ne 0)$ + +证明方式:定义 + +根据法则2:$(Cu)^{'}=Cu^{'}$ + +> 反函数的导数等于直接函数导数的倒数 diff --git a/docs/AssemblyLanguage.md b/docs/AssemblyLanguage.md new file mode 100644 index 0000000..2539330 --- /dev/null +++ b/docs/AssemblyLanguage.md @@ -0,0 +1,1502 @@ +*written by PeterAlbus,Copyright © 2022 - SHOU 1951123 Hong Wu* + +写在前面:本学期这门课在课表上的名称叫《微机原理与接口技术》,冯老师为我们选的课本则是王爽老师的《汇编语言(第四版)》,开学的课上讲的也非常清楚,希望通过汇编语言=>理解微机原理与接口技术。实际效果倒是较为微妙。由于本笔记是根据课本编写,在反复研读了课本内容后,最终我还是决定把标题定为“汇编语言” + +# 汇编语言 + +## 附录 寄存器 + +8086CPU的14个寄存器:AX,BX,CX,DX,SI,DI,SP,BP,IP,CS,SS,DS,ES,PSW + +通用寄存器 :AX,BX,CX,DX + +用来存放一般性的数据。可以存放16位数据。这四个寄存器也都可以拆分为两个可独立使用的8位寄存器 + ++ CX 用于循环,loop指令在循环结束时会使CX-1,并使用CX判断是否继续执行 ++ BX可以出现在[]作寻址用 ++ AX和DX在div指令中会用于存放被除数 + + + +段寄存器:CS,DS,SS,ES + +用来在CPU访问内存时提供段地址 + ++ CS:程序段寄存器 ++ DS:数据段寄存器 ++ SS:栈段寄存器 + + + +指令指针寄存器:IP + +存放下一条要执行的指令所在位置相对于CS的段内偏移 + + + +栈顶寄存器:SP + +存放栈顶的段内偏移 + + + +不可拆分为两个八位寄存器的寄存器:SI,DI,BP + +都可以用于寻址,BP与BX类似,SI或DI则可以与BP或BX组合,同时出现两个寄存器在[]中进行寻址 + +使用BX时,隐式的段地址为DS,使用BP时,隐式的段地址为SS + + + +标志寄存器:PSW,书中简称为flag,有9个有效的标志位,具体含义在第11章 + +## 第一章 基础知识 + +### 1.1 机器语言 + +机器语言是机器指令的集合。 + +通过将一串二进制数字传递给计算机(过去,程序员使用打孔的方式编程),即一串由0和1组成的序列。 + +计算机读取机器码进行执行。 + +### 1.2 汇编语言的产生 + +由于机器码的晦涩难懂,难以记忆,产生了汇编语言。汇编语言把机器码用接近人类语言的方式表示,便于记忆。 + +例如想要把寄存器BX的内容送到AX中: + +机器指令:1000100111011000 + +汇编指令:`mov ax,bx3` + +程序员通过汇编指令编写源程序,通过编译器把汇编指令转换成机器码,交给计算机,由计算机最终执行。 + +### 1.3 汇编语言的组成 + +汇编语言由3类指令组成: + ++ 汇编指令:可以转换为对应的机器码 ++ 伪指令:没有对应的机器码,由编译器执行,辅助编译器进行编译(与编译器沟通的桥梁) ++ 其他符号:如+,-,*,/等,由编译器识别 + +### 1.4 存储器 + +CPU负责控制计算机以及进行运算。CPU的工作需要两个内容:指令和数据。 + +指令和数据在存储器中存放。 + +汇编语言的核心就是通过将指令写入内存,让CPU从内存中读取指令,并通过这些指令控制CPU对于内存/寄存器中的数据进行计算。 + +### 1.5 指令和数据 + +在内存和磁盘上,指令和数据没有区别,都是一串二进制信息。 + +计算机在程序运行时,会把内存中的程序读取到寄存器内进行执行,此时这一串二进制信息会被解析为指令。 + +而计算机也可以把同样一段二进制信息当作简单的数据访问。 + +### 1.6 存储单元 + +存储器会被划分为若干个存储单元,从0开始编号。 + +一个微型计算机的存储单元可以存储8位二进制数,即8个**bit**(比特/位)。8个bit相当于1个**Byte**(字节)。 + +微型存储器的容量以字节为最小单位来计算。 + +### 1.7 CPU对存储器的读写 + +CPU在读取内存中的数据时,要和存储器芯片交互以下数据: + ++ CPU给出要操作的存储单元的地址信息——通过地址总线传输 ++ CPU给出要对存储单元进行怎么样的操作(读/写)——通过控制总线传输 ++ CPU给出要写入的数据或存储器芯片给出读出的数据——通过数据总线传输 + +地址总线、控制总线和数据总线就是总线根据传送信息的不同,从逻辑上分为的三个类别 + +### 1.8 地址总线 + +地址总线传递的信息数量决定了CPU能够对多少存储单元进行寻址。 + +一个CPU有n根地址线,则可以说这个CPU的地址总线的宽度为N,这样的CPU可以寻找2^N^个内存单元 + +### 1.9 数据总线 + +数据总线的宽度决定了CPU和外界传送数据的速度。8根数据总线一次可传送8位二进制数据(一个字节)。 + +8086cpu(汇编语言的学习基本都将基于本cpu)是16位cpu,有16根数据总线,一次可传送16位二进制数据。 + +### 1.11 内存地址空间 * + +cpu将系统中的各类存储器看作一个逻辑存储器,通过总线能访问到这个逻辑存储器的各个地址空间。这个逻辑存储器就是汇编语言中要面对的整个内存地址空间。 + +![image-20220104214311196](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220104214311196.png) + +## 第二章 寄存器 + +典型的CPU由运算器、控制器、寄存器组成。它们由CPU的内部总线相连(外部总线见第一章,访问内存地址空间) + +对于汇编语言程序员,主要需要面对和操作的就是CPU的寄存器,在汇编的代码中,直接写寄存器的名称即可访问寄存器。 + +8086CPU有14个寄存器:AX,BX,CX,DX,SI,DI,SP,BP,IP,CS,SS,DS,ES,PSW + +课本选择不对该14个寄存器进行一次性介绍。而本笔记作为学期末的整理,会将常用的寄存器功能和汇编程序指令整理在本文开头的附录中。 + +### 2.1 通用寄存器 + +8086CPU的所有寄存器都为16位,可以存放两个字节。 + +AX,BX,CX,DX是8086的四个通用寄存器,用于存放一般性的数据。 + +AX占用16个存储单元:0-15, + +第0个存储单元存储最低位数据,第15个存储单元存储最高位数据。 + +为了和上一代的8位寄存器兼容,这四个寄存器也都可以拆分为两个8位寄存器。 + +例如AX可拆分为AH和AL。AH代表AX的高八位(high),AL代表AX的低八位(low)。 + +### 2.2 字在寄存器中的存储 + +8086CPU可以一次处理两种尺寸的数据,字节可以存放在8位寄存器中,一个字有两个字节(对于16位CPU来说),可以存储在一个16位寄存器中。 + +在学习完整个汇编语言后,回头看该章节意义如下:提示汇编中通过地址取出值,可能取出该地址后的一个字节,也可能取出该地址后的一个字 甚至两个字。明确指出的例子有`jump dword ptr`和`jump word ptr`的区别,隐含的则例如`mov ax,ds:[0]`和`mov ah,ds:[0]`从`ds:[0]`取出的值位数是不一样的。 + +> 在讨论寄存器中的数据时,常常使用十六进制描述,因为十六进制和二进制为固定的4位对应一位,可以直观地看出数据的位数。为了区分不同的进制,十六进制数据后会加上H(HEX),二进制数据的后面会加上B(Binary),十进制数据后面则什么也不加。例如:20000,4E20H,0100111000100000B + +### 2.3 几条汇编指令 + +该章节正式开始了汇编指令的学习。在写一条汇编指令或一个寄存器名称的时候不区分大小写。 + +本章节作为汇编语言的入门,主要学习了`mov`和`add`两条指令。 + +`mov`可以将一个数据存入寄存器,也可以将另一个寄存器或是内存中的数据存入寄存器。 + +`add`则可以对两个数据进行加法运算,其中第参数必须是寄存器,结果将会存储在该寄存器中。 + +使用举例(汇编语言以一行作为一条指令,结尾不需要分号,分号起到注释的作用): + +```assembly +mov ax,18 ;将数据18送入寄存器AX +mov ah,78 ;将数据78送入寄存器AH +add ax,8 ;将寄存器AX中的数值加上8 +mov ax,bx ;将寄存器BX中的数据送入寄存器AX +add ax,bx ;将AX和BX相加,结果存储在AX中 +``` + +对于上面的指令,在c语言中表示如下: + +```c +ax=18; +ah=78; +ax+=8; +ax=bx; +ax+=bx; +``` + +注意事项: + ++ 两个操作对象的位数应当是一致的,例如`mov ax,bh`是不合法的指令。 ++ 加法若产生进位,寄存器当中没有空间进行储存,将会丢失。 + +### 2.4 物理地址 + +上述的用例交给CPU处理的都是简单的数据或寄存器。如果要访问内存单元,则需要给出内存单元的地址。CPU需要通过存储器的地址总线将存储器的物理地址送入存储器。8086CPU如何形成这个物理地址将在接下来的部分讨论。 + +### 2.5 16位结构的CPU + +由于8086为16位CPU,16位结构描述了CPU具有以下几个方面的特性。 + ++ 运算器一次最多处理16位数据。 ++ 寄存器最大宽度为16位。 ++ 寄存器和运算器之间通路为16位。 + +因此8086对于地址数据也仅仅一次能传输16位。 + +### 2.6 8086CPU给出物理地址的方法 + +8086是16位CPU,但有20位的地址总线 + +为了发出20位的地址,8086CPU将两个16位地址合成一个20位的物理地址。 + +这两个16位地址分别是**段地址**和**偏移地址**。 + +![image-20220104214404065](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220104214404065.png) + +地址加法器采用 **物理地址=段地址*16+偏移地址** 的方法合成物理地址。 + +### 2.7 “段地址*16+偏移地址=物理地址”的本质含义 + +CPU在访问内存时,用一个基础地址(段地址*16)加上一个相对于基础地址的偏移,给出了物理地址。 + +而段地址*16是在十进制下的表现。对于原理的解释,在十六进制下更加清晰。 + +对于十六进制:段地址\*16即为段地址\*10H,即段地址后增添一个0。 + +通过这种方法就可以用4位十六进制(16位二进制)表达更大范围(5位十六进制,20位二进制)的基础地址,而这样表达的精确度不够(基础地址只能是16的倍数),就使用偏移地址来进行修正。 + +### 2.8 段的概念 + +尽管有段地址的概念,不代表内存被划分成了一个个段,每个段对应一个固定的段地址。 + +段的划分是虚拟的,不同的段地址加上不同的偏移地址仍可以表示同一个内存单元。 + +同一个段地址,由于偏移地址有16位,最大可以寻找64KB的内存单元,因此虚拟上,一个段的最大长度为64KB。 + +### 2.9 段寄存器 + +8086CPU有4个段寄存器,用于在访问内存时提供4个段的段地址:CS,DS,SS,ES + +### 2.10 CS和IP + +CS和IP是8086CPU最重要的两个寄存器。它们只是了CPU当前要读取指令的地址。 + +CS为代码段寄存器,IP为指令指针寄存器。 + +任意时刻,当8086CPU需要执行一条指令时,会读取CS和IP中的值,通过地址加法器得出物理地址,然后通过该物理地址从CPU取出一条指令放入内存并执行,此时IP指向下一条指令。 + +*8086CPU中,需要取出的指令长度可以通过读取到的前16个字节获取* + +### 2.11 修改CS、IP的指令 + +对于AX等通用寄存器中的值,可以使用`mov`指令修改,但CS,IP是不能用该指令设置的。 + +能修改CS、IP的指令统称为转移指令,最简单的指令为`jmp` + +```assembly +jmp 2AE3:3 ;执行后CS=2AE3H,IP=0003H,注意,这种形式仅可在Debug中使用而编译器不识别 +``` + +若仅仅想修改IP,也可用如下用法: + +```assembly +jmp ax ;用ax寄存器的值修改IP,含义上类似mov IP,ax +``` + +### 2.12 代码段 + +我们可以将长度为N(<64KB)的一段代码,存在一组地址连续,起始地址为16倍数的内存单元中。 + +而计算机并不知道这是一段代码段。 + +只要将CS:IP修改为指向这段内存单元的起始地址(第一条指令的首地址),CPU就会把这段数据当作指令进行处理。 + +> 对于汇编语言的学习,最佳还是进行编程和运行进行调试,这个过程需要使用DOSBox模拟8086CPU的环境,限于作者精力和篇幅,详细使用方式将不会在笔记中出现,可自行通过课本或搜索引擎进行学习。因此课本上debug相关的内容可能突兀地出现在接下来的笔记中,见谅。 + +## 第三章 寄存器(内存访问) + +### 3.1 内存中字的存储 + +CPU中使用16位寄存器储存一个字,高八位存放高位字节,低八位存放低位字节。 + +如果用0、1两个内存单元存储数据20000(4E20H),4E将存储在编号为1的内存单元中,20将存储在20的内存单元中。 + +这两个单元可以看作一个起始地址为0的字单元。 + +### 3.2 DS和[address] + +CPU要读写一个内存单元的时候,必须先给出这个内存单元的地址。8086CPU有一个DS寄存器,通常用来存放数据的段地址。当使用[address]时,将默认把ds作为段地址,address作为段内偏移。 + +例如想要读取10000H单元的内容,可以用如下的程序段进行: + +```assembly +mov bx,1000H +mov ds,bx +mov al,[0] +``` + +这里的`[0]`说明想要送入al的值段内偏移为0,而段地址则自动从ds中取出。 + +为何将段地址1000H送入ds要先将其送入bx? + +因为8086CPU不支持直接将数据传入段寄存器(这属于8086CPU硬件设计问题,不必深究)。 + +### 3.3 字的传送 + +mov指令可以进行字节型数据的传输,也可以进行字的传输。只要给出16位寄存器就可以进行16位数据的传送。 + +### 3.4 mov,add,sub指令 + +mov,add,sub指令都有两个操作对象,它们有以下几种格式: + +```assembly +mov 寄存器,数据 +mov 寄存器,寄存器 +mov 寄存器,内存单元 +mov 内存单元,寄存器 +mov 段寄存器,寄存器 +mov 寄存器,段寄存器 +mov 内存单元,段寄存器 +mov 段寄存器,内存单元 +add 寄存器,数据 +add 寄存器,寄存器 +add 寄存器,内存单元 +add 内存单元,寄存器 +sub 寄存器,数据 +sub 寄存器,寄存器 +sub 寄存器,内存单元 +sub 内存单元,寄存器 +``` + +### 3.5 数据段 + +对于8086CPU,可将一段连续的内存单元存放代码,作为代码段。 + +同样的,可以讲一段内存作为数据段,通过ds存储数据段的段地址。 + +### 3.6 栈 + +栈是一种具有特殊访问方式的存储空间,最后进入这个空间的数据,最先被取出。 + +### 3.7 CPU提供的栈机制 + +8086CPU提供相关的指令来以栈的方式访问内存空间。 + +最基本的两个是PUSH和POP。 + +`pop ax`表示从栈顶取出数据送入ax。 + +`push ax`表示将ax的数据送入栈中。 + + + +CPU通过SS和SP两个寄存器确定栈的位置。 + +**任意时刻,SS:SP指向栈顶元素** + +`push ax`执行时,由以下两步完成 + ++ SP=SP-2,让SS:SP指向栈顶前面的单元 ++ ax中的内容送入SS:SP指向的内存单元处 + +`pop ax`执行时的动作则相反 + ++ 将SS:SP指向的内存单元处的字取出放入ax ++ SP=SP+2 + +### 3.8 栈顶超界的问题 + +通过SS和SP仅仅能保证在出栈和入栈时能找到栈顶的位置。 + +当栈为空时使用pop或栈为满时使用push,可能会面临栈顶超界的问题。这是危险的,可能会覆盖栈外有效的数据。 + +8086CPU并没有寄存器记录栈的大小,在使用中需要程序员注意栈顶超界的问题。 + +### 3.9 push和pop指令 + +这两个指令可以是如下格式: + +```assembly +push 寄存器 +pop 寄存器 +push 段寄存器 +pop 段寄存器 +push 内存单元 +pop 内存单元 +``` + +例子: + +将10000H~1000FH这段空间当作栈,初始为空,将AX、BX、DS中的数据入栈 + +```assembly +mov ax,1000H +mov ss,ax +mov sp,0010H ;设置初始栈顶位置 +push ax +push bx +push ds +``` + +加入将10000H-1000FH这段空间当作栈,数据从1000F开始填充,直到填满时栈顶为10000H,因此初始状态栈顶为0010H,当push数据时,sp=sp-2,栈顶变为1000E,写入两个字节的数据到1000E和1000F。 + +### 3.10 栈段 + +与代码段,数据段类似,我们可以将一组连续的内存单元(依旧是小于64kb,起始地址为16的倍数)当作栈空间使用,将SS:SP指向这个栈,从而定义了一个栈段。栈中没有元素时,SS:SP指向栈的最底部单元下面的单元。参考3.9末尾的分析。 + +## 第四章 第一个程序 + +在先前的章节中,仅仅讲述了一些简单的汇编指令和寄存器,对他们的测试可以通过DOSBox中的Debug进行。而本章节将会讲述编写一个完整的汇编语言程序,之后用编译和连接程序将他们编译连接成可执行文件的过程。 + +### 4.1 一个源程序从写出到执行的过程 + ++ 使用文本编辑器编写汇编源程序 + ++ 对源程序进行编译连接 + ++ 执行可执行文件中的程序 + + 这一步操作系统会按照可执行文件的描述信息,把可执行文件中的机器码加载入内存,并进行相关初始化(设置CS:IP) + +![image-20220105181500362](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220105181500362.png) + + + +### 4.2 源程序 + +一段简单的汇编语言源程序: + +```assembly +assume cs:codesg + +codesg segment + + mov ax,0123H + mov bx,0456H + add ax,bx + add ax,ax + + mov ax,4c00H + int 21H + +codesg ends + +end +``` + +1. 伪指令 + + 源程序中包含汇编指令和伪指令。汇编指令有对应的机器码,最终会被编译为机器指令。伪指令则用来辅助编译器进行相关的编译工作。该源程序中出现了3种伪指令: + + + ```assembly + XXX segment + XXX ends + ``` + + segment和ends是一对成对使用的伪指令。功能是定义一个段,XXX位置填写标记段的段名。在定义段后,会有其他很多地方用到段,将在稍后介绍。 + + + `end` + + 注意:end与ends并不是相同的指令。end用于标记一个汇编程序的结束。汇编源程序种必须有结束的标记。 + + + `assume` + + 该伪指令含义为“假设”,用于把某一寄存器和定义的段关联。前方用segment...ends定义的段就在此处进行使用。在实例的源程序中,`assume cs:codesg`把定义的名为`codesg`的段与cs寄存器关联,即设置段寄存器cs的值为`codesg`段的段首地址。 + + > 笔记作者简评:assume指令常用于把程序中的代码段赋值给cs,另外常用的写法是`assume ds:datasg`和`assume ss:stacksg`等,但在之后章节的学习中,ds的值往往在程序中仍需要重新进行一次赋值,通过assume指令设置的ds值在内存中观察,会和实际的ds值相差10h(这是由于PSP的缘故),而assume cs也未必可靠,如果代码段不是程序中的第一段,仍需要加一个`start`和`end start`的伪指令来标记程序的入口,因此,assume指令的意义到底如何,笔者仍在思考中。 + +2. 源程序中的程序 + + 程序代码由编译器处理 + + ![image-20220105184026826](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220105184026826.png) + +3. 标号 + + 在伪指令中定义的标号,如`codesg`,最终将被编译、连接程序处理为一个段的段地址。 + +4. 程序的结构 + + 对于汇编程序结构的总结:编写一个个段,代码段存放要执行的指令,数据段栈段存放数据,使用assume将它们和寄存器连接起来。最后指出程序在何处结束。 + +5. 程序返回 + + 我们的程序在编译后将最终在DOSBox的DOS系统中运行,DOS系统有一个程序,调用编译连接好的程序的可执行文件,将CPU交给这个程序。而这个程序运行完成后,也要把控制权交回给调用它运行的程序,这个过程称为返回。 + + 程序返回的指令为: + + ```assembly + mov ax,4c00H + int 21H + ``` + + 返回的原理是调用编号为4c的中断,具体理由不必深究。只需了解这两条指令可以实现程序返回。 + +6. 语法错误和逻辑错误 + + 与其他高级语言类似,编译器在程序编译器可以发现语法错误,但逻辑错误只有在程序运行时才能被发现。 + +### 4.3-4.7 源程序的编辑、编译、连接以及exe可执行文件的执行 + +这几个章节主要内容为DOSBox中编译源程序以及执行文件的过程。 + +通过masm指令对于.asm文件进行编译,生成.obj文件。 + +通过link指令对.obj文件进行连接,生成exe文件。 + +最终在目录下输入exe文件名即可执行编写的程序。 + +### 4.8 谁将可执行文件中的程序装载 + +DOS系统中有一个command程序,我们在DOSBox中输入指令,都由这个程序读取、执行、输出结果。 + +当直接执行exe文件时,则是这个command程序把可执行文件加载到内存中。执行完毕后返回,CPU重新开始运行command。 + +![image-20220105185552693](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220105185552693.png) + +### 4.9 程序执行过程的跟踪 + +想要观察程序的执行过程,可以使用`Debug 1.exe`,这条指令会使用Debug将可执行文件加载入内存,但Debug仍然不放弃对CPU的控制权,你可以通过Debug的相关命令对程序的运行过程进行观察。 + +r指令可以查看寄存器的情况。 + +t指令可以单步执行(到了int,需要使用p指令) + +d指令可以查看指定地址的内存 + +DOS系统EXE文件中程序的加载过程如下: + +![image-20220105190708223](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220105190708223.png) + +加载完毕后,ds存放着程序所在内存区的段地址(SA)。偏移为0。 + +这个内存区的前256个字节存放的则是PSP,DOS用来和程序通信。 + +因此,源代码中的程序开始,地址为SA+10H:0 + +## 第五章 [BX]和loop指令 + +[BX]和[0]类似,表示内存单元,偏移地址为0/BX中的数值。段地址一样默认在ds中 + +与课本相同,本笔记也将使用()来表示一个寄存器或一个内存单元中的内容,使用idata代表一个常量。 + +### 5.1 [BX] + +使用举例 + +```assembly +mov ax,[bx] +mov [bx],ax +``` + +BX中的数据作为一个偏移地址EA + +第一条指令表示把DS:EA的数据送入AX,第二条指令表示把AX中的数据送入内存DS:EA。 + +### 5.2 Loop指令 + +loop指令格式为:loop 标号。 + +标号是在源代码中对一条指令的标记,标号代表一个地址,这个地址处有一条指令。 + +当CPU执行loop指令时,要进行两步操作 + ++ (cx)=(cx)-1 ++ cx中的值不为0,就转至标号处,执行标号处的程序 + +因此我们常用loop指令来实现循环功能,cx中存放循环次数。 + +使用样例: + +```assembly +assume cs:code +code segment + + mov ax,2 + mov cx,11 +s: add ax,ax + loop s + + mov ax,4c00h + int 21h +code ends +end +``` + +该程序的目的是计算2^12 + +这里的s就代表一个地址,这个地址处有一条指令:`add ax,ax` + +### 5.3 在Debug中跟踪还loop指令实现的循环程序 + +该段根据课本实际上级操作可以加深对loop的理解。 + +使用u 0B3D:0命令可以查看内存中的程序 + +使用g 0012命令可以让程序直接运行跳转到(IP)=0012h的位置 + +使用p命令可以一次将所有loop执行完,直到cx=0 + +### 5.4 Debug和汇编编译器masm对指令的不同处理 + +对于Debug,[0]将被视为一个偏移为0的内存单元中的数值,而对于masm,[0]将被视为一个常量。 + +因此在编写汇编源程序时,如果要将常量作为偏移地址,必须在之前显式的给出段地址,例如`ds:[0]` + +### 5.5 loop和[bx]的联合应用 + +可通过loop的每次循环,更改bx的值(`inc bx`),实现对内存单元的遍历。 + +本章节还提到,如果需要累加多个占1个内存单元的数据,但它们的和占用两个内存单元,可以先用字寄存器做中专,然后累加ax这种字寄存器。 + +### 5.6 段前缀 + +仅仅通过[]给出偏移地址时,段地址默认在ds中,而也可以显式的给出其他段寄存器来作为段地址,这在汇编语言中被称为段前缀。例如:`cs:[bx]` + +### 5.7 一段安全的空间 + +使用汇编语言在DOS系统中操作内存时,有权利操纵那些存储着重要信息的内存,而不像windows,unix等系统对于重要的硬件有层层的保护。因此我们必须保证我们操作的内存没有其他程序使用。直接用汇编语言去操作真实的硬件,了解早已被层层系统软件掩盖的真相也正是汇编语言的魅力所在。 + +DOS和其他的合法程序一般不会使用0:200-0:2ff这段空间,以后我们需要直接向内存写入内容时,一般会使用这段空间。 + +### 5.8 段前缀的使用 + +想要将内存`ffff:0~ffff:b`中的数据复制到`0:200~0:20b`中 + +可以先把`0:200~0:20b`看作`0020:0~0020:b`,让两者的偏移地址相同 + +之后通过两个不同的段寄存器储存段地址,使用两个段前缀,就可以快速的在两个段间传递数据。 + +## 第六章 包含多个段的应用程序 + +0:200-0:2ff这段空间相对安全,而如果想要使用更多空间,需要合法的通过操作系统取得空间。 + +想要合法的取得空间,可以在加载程序的时候为程序分配,也可以在程序执行的过程中向系统申请。本课程中将仅学习第一种方法。 + +在先前的程序中,汇编程序都合法的获得了操作系统分配的代码段空间。如果想要在程序被加载的时候分配到空间,需要在源程序中进行说明。一般不同用途的空间(栈、数据),会通过不同的代码段来区分。 + +接下来的内容将先尝试不适用多个段,在同一个段中存放数据、代码、栈,之后尝试了解程序中使用多个段。 + +### 6.1 在代码段中使用数据 + +如何找到一串连续的内存单元存储数据? + +规范的角度,我们应当让系统来为我们分配。我们可以在程序中定义数据,这些数据被编译连接后放入可执行文件中,可执行文件的程序被加载入内存时,这些被定义的数据也会被分配一段空间,加载到内存中。 + +例: + +```assembly +assume cs:code + +code segment + + dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h + + mov bx,0 + mov ax,0 + mov cx,8 +s: add ax,cs:[bx] + add bx,2 + loop s + + mov ax,4c00h + int 21h + +code ends + +end +``` + +这里使用了dw,含义为define word,此处使用dw定义了8个字形数据,每个占用两个存储单元(16字节) + +在程序执行过程中,因为这些数据放在程序段的开头,所以可以通过cs作为段地址,加上段内偏移找到这些数据。 + +但又因为这段数据放在了程序段的开头,这段数据也会被作为程序加载并尝试执行,这个过程会出错。为了解决这个问题,需要手动设置ip指向第一行代码,或者使用如下操作: + +```assembly +assume cs:code + +code segment + + dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h + +start: + mov bx,0 + mov ax,0 + mov cx,8 +s: add ax,cs:[bx] + add bx,2 + loop s + + mov ax,4c00h + int 21h + +code ends + +end start +``` + +这里在程序的第一条代码前加上了标号start,同时在end处加上了start这个标号。 + +这样,end指令不仅可以向编译器告知程序的结束位置,也可以向编译器描述程序的入口,可执行文件运行时会根据入口修改CS:IP指向的位置。 + +![image-20220105202240433](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220105202240433.png) + +### 6.2 在代码段中使用栈 + +要在代码段中使用栈,和使用数据类似,需要获得一段合法的内存空间,然后将SS:SP指向它。 + +想要获得合法的内存空间,依旧可以使用dw: + +```assembly +dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +``` + +这样定义16个字型数据,将取得16个字的内存空间,将栈顶指向这个数据段的后一个单元,就可以把这段数据当作栈使用。 + +### 6.3 将数据、代码、栈放入不同的段 + +将数据、代码、栈放到同一个段中的限制: + ++ 程序混乱 ++ 一个段的容量不能超过64KB(8086cpu的限制) + +想要用多个段来存放数据、代码、栈,做法如下所示: + +```assembly +assume cs:code,ds:data,ss:stack + +data segment + dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h +data ends + +stack segment + dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +stack ends + +code segment +start: + mov ax,stack + mov ss,ax + mov sp,20h + mov ax,data + mov ds,ax + mov bx,0 + mov cx,8 +s: push [bx] + add bx,2 + loop s + mov bx,0 + mov cx,9 +s0: pop [bx] + add bx,2 + loop s0 + + mov ax,4c00h + int 21h + +code ends +end start +``` + ++ 定义多的段的方法:和代码段并无不同,只要每个段有不同的段名即可 + ++ 如何引用段地址:我们可以注意到,想要使用data的段地址,直接通过`mov ax,data`就可以把data段的段地址送入AX。一个段中数据的段地址可以由段名代表,而段偏移则需要看它在段中的位置。 + + 注意点就是和常量一样,不可以直接通过段名将段地址送到段寄存器中,要用普通寄存器做中转。data这样的段名会被编译器解析成一个数值。 + +## 第七章 更灵活的定位内存地址的方法 + +之前访问内存地址,[]内往往是单一的寄存器或idata,实际上可以用更灵活的方式定位这些地址,方便编程的过程。如果理解困难,可以翻看课本,通过具体问题理解这些特性该怎么使用。本笔记将仅仅简单地介绍这些特性。 + +### 7.1 and和or指令 + ++ and指令:逻辑与指令,两个操作数将按位与进行运算,结果存储在第一个操作数的位置 ++ or指令:逻辑或指令,两个操作数将按位进行或运算 + +### 7.2 关于ASCII码 + +ASCII码是一种编码方案,约定了用什么样的信息表示现实对象,例如用61H表示字符a。 + +当把这样的数据送到需要显示文字的地方,将会被解析为对应的字符。 + +### 7.3 以字符形式给出的数据 + +在汇编程序中,也可以以'.....'的形式以字符形式给出数据,存储在内存中时,它们将自动转换为ASCII码。 + +例如: + +```assembly +db 'unIX' +db 75H,6EH,49H,58H +``` + +这两行代码是等价的 + +Debug中使用d命令查看data时,也会以ASCII字符的形式显示出其中的内容。 + +### 7.4 大小写转换 + +由于大小写字母的ASCII码有如下规律:出了第五位外,大小写的其他各位都一样。因此要把数据置为大写,只要将第五位置为0,反之则能把数据置为大写。 + +这个操作可以用and和or指令完成。 + +and al,11011111可以将al内数据置为大写字母 + +or al,00100000可以将al内数据置为小写字母 + +### 7.5-7.10 不同的寻址方式 + ++ [idata]使用一个常量来表示地址,可以直接定位一个内存单元 ++ [bx]用一个变量来表示内存地址,可以用于间接定位一个内存单元 ++ [bx+idata]使用了一个常量和一个变量,可以在一个起始地址的基础上定位内存单元(数组) ++ [bx+si]用两个变量表示地址 ++ [bx+si+idata]用两个变量和一个常量表示地址 + +在实际程序的编写过程中,往往会有许多灵活的寻址需求,比如需要操作多个连续字符串里的每个字符等,灵活运用这些不同的寻址方式可以事半功倍。 + +简单总结可以说,在8086CPU中,可以出现在[]内用作寻址的寄存器有bx,si,di和之后会提到的bp,这四个寄存器可以单个出现,也可以从bx、bp中任选一个以及从si、di中任选一个,两两出现。此外[]内还可以出现idata。 + +## 第八章 数据处理的两个基本问题 + +本章节大致总结了计算机在数据处理过程中数据在哪,数据多长的问题。 + +### 8.1 bx,si,di和bp + +如同第七章末尾内容,这四个寄存器可以用于寻址。 + +以下的用法都是合法的: + +```assembly +mov ax,[bx] +mov ax,[si] +mov ax,[di] +mov ax,[bp] +mov ax,[bx+si] +mov ax,[bx+di] +mov ax,[bp+si] +mov ax,[bp+di] +mov ax,[bp+si+idata] +mov ax,[bp+di+idata] +mov ax,[bx+si+idata] +mov ax,[bx+si+idata] +``` + +在[...]中若使用bp,则不同于使用其他时候的ds,隐式的段地址默认为ss + +### 8.2 机器指令处理的数据在什么地方 + +![image-20220105220240959](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220105220240959.png) + +### 8.3 汇编语言中数据位置的表达 + ++ 立即数(idata),在汇编指令中直接给出 ++ 寄存器,在汇编指令中给出寄存器名 ++ 段地址(SA)和偏移地址(EA),用SA:[EA]的方式给出,SA可以不写使用默认的,EA的各种灵活寻址方式在上一章刚刚介绍 + +### 8.4 寻址方式 + +寻址方式的详细介绍已在第七章给出,这里给出书上总结的表格 + +![image-20220105220601144](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220105220601144.png) + +### 8.5 指令要处理的数据有多长 + +对于8086的CPU,既可以处理byte(8位二进制,一个字节)尺寸的数据,也可以处理word(16位二进制,两个字节,一个字)尺寸的数据。进行的是字操作还是字节操作,汇编语言会以以下方式处理: + ++ 通过寄存器名指明要处理的数据尺寸 + ++ 在没有寄存器名存在的情况下,可以用<操作符> ptr的形式,指定要访问的内存单元的长度,<操作符>可以是word或byte + + ```assembly + mov word ptr ds:[0],1 + mov byte ptr ds:[0],1 + ``` + + 没有寄存器存在时,显式指明要访问的内存单元长度非常有必要。 + ++ 有的指令则会默认访问的是字还是字节 + + 例如push指令,只进行字操作 + +### 8.6 寻址方式的综合应用 + +教材通过一个样例的方式,传达了一种结构化寻址的思想。 + +例如一个结构化的数据包含了多个数据项,可以通过`[bx+idata+si]`的方式访问结构体的数据。`bx`定位整个结构体,`idata`定位结构体的某个数据项,`si`定位这个数据线的每个元素。 + +这种定位方式可以通过更加贴切的书写方式: + +`[bx].idata`和`[bx].idata[si]`表示 + +例如:`[bx].10h[si]` + +### 8.7 div指令 + +div指令用于进行除法运算。 + +div指令的格式为: + +```assembly +div 寄存器 +div 内存单元 +``` + ++ 除数有8位和16位两种,存储在寄存器或内存单元中 ++ 如果除数有8位,被除数则有16位,存放在AX中,如果除数有16位,被除数则有32位,存放在AX和DX中 ++ 如果被除数为16位,则AL会存储除法操作的商,AH会存储除法的余数。如果被除数有32位,则会在AX中存储除法操作的商,DX存储除法操作的余数 + +### 8.8 伪指令dd + +db用来定义字节数据,dw用来定义字型数据。 + +dd用于定义dword双字数据。 + +使用dd定义的数据会占用两个字。 + +### 8.8 dup + +dup使用时和dw,db,dd等数据定义伪指令配合使用,用于进行数据的重复 + +例: + +```assembly +db 3 dup (0) +db 0,0,0 +``` + +上面的两行代码是等价的,使用dup重复定义了3次0 + +```assembly +db 3 dup (0,1,2) +db 0,1,2,0,1,2,0,1,2 +``` + +上面的两行代码亦是等价的,使用dup相当于重复的进行了三次定义 + +## 第九章 转移指令的原理 + +在第二章2.11部分,提到过**可以修改IP,或同时修改CS和IP的指令统称为转移指令**。 + +概括地讲,转移指令用于控制CPU执行内存中某处的代码。 + +8086CPU的转移指令分为以下几类: + ++ 无条件转移指令 ++ 条件转移指令 ++ 循环指令 ++ 过程 ++ 中断 + +### 9.1 操作符offset + +offset是由编译器处理的符号,它的功能是取得标号的偏移地址。例如下面的程序: + +```assembly +assume cs:codesg +codesg segment + + start:mov ax,offset start ;相当于mov ax,0 + s:mov ax,offset s ;相当于mov ax,3 + +codesg ends +end start +``` + +上面的代码通过offset操作符取得了标号start的偏移地址0和s的偏移地址3 + +### 9.2 jmp指令 + +jmp位无条件转移指令,可以只修改IP,也可以同时修改CS和IP + +jmp指令要给出两种信息。 + ++ 转移的目的地址 ++ 转移的距离(段间转移、段内短转移、段内近转移) + +### 9.3 依据位移进行转移的jmp指令 + +```assembly +jmp short 标号 +``` + +该格式的jmp指令可以实现段内短转移。它可以使IP向前转移时最多越过128个字节,向后转移时最多越过127个字节。 + +指令中的标号则是代码段中的标号。使用举例如下: + +```assembly +assume cs:codesg + +codesg segment +start: + mov ax,0 + jmp short s + add ax,1 +s: + inc ax +codesg ends + +end start +``` + +这里的jmp short s可以实现将ip转移到标号s处,即cs:0008处的功能。但如果将这句汇编语言翻译成机器码,将会是EB03,机器码中并没有给出转移终点的段内偏移。这是因为**CPU在执行jmp指令时不需要转移的目的地址**,在机器码中储存的是转移的位移,例如上面的例程,转移指令代表将IP=IP+3,就能够跳转到s标号的位置。这个位移是由编译器计算出来的。 + +因此,`jmp short 标号`的功能为实现:(IP)=(IP)+8位位移,由于位移是8位,因此范围为-128~127 + +与此功能相似,`jmp near ptr 标号`功能为:(IP)=(IP)+16位位移,位移为16位因此范围位-32768~32767 + +以上两条指令的位移量都是由编译程序在编译时算出的。位移=标号处地址-jmp指令后第一个字节的地址。 + +### 9.4 转移的目的地址在指令中的jmp指令 + +以上的指令中jmp编译为机器指令后,都是根据相对位置进行转移。 + +`jmp far ptr 标号`则可以实现段间转移,又称为远转移。 + +编译器在编译该指令后,会在机器码中出现标号处的段地址和偏移地址,用这些数据修改CS和IP。 + +### 9.5 转移地址在寄存器中的jmp指令 + +`jmp 16位寄存器` + +该指令在2.11节已经进行过介绍 + +### 9.6 转移地址在内存中的jmp指令 + +以下两种格式的指令可以实现转移地址在内存中的jmp指令: + ++ `jmp word ptr 内存单元地址` + + 该指令实现段内转移,从内存单元地址处开始存放着一个字,是转移的目的偏移地址,内存单元地址可以用第七章讲述的任意寻址方式给出 + ++ `jmp dword ptr 内存单元地址` + + 实现段间转移,从内存单元地址处开始存放着两个字,高地址处的字是转移的目的段地址,低地址处是转移的目的偏移地址。 + +### 9.7 jcxz指令 + +jcxz指令为有条件转移指令,所有的有条件转移指令都是短转移,根据相对位移进行转移 + +指令格式:`jcxz 标号` + +该指令的功能为,如果cx==0,则执行`jmp short 标号` + +### 9.8 loop指令 + +loop指令为循环指令,循环指令也是短转移指令。 + +我们先前已经多次使用loop指令,通过这些章节的学习,不难看出`loop 标号`指令的功能为: + ++ 先将cx减一 + ++ 之后执行`jcxz 标号`指令,即如果cx==0,则执行`jmp short 标号` + +### 9.9 根据位移进行转移的意义 + +为何对IP的修改会有许多指令是根据相对位置进行修改? + +在接下来的章节中,常常有内容会需要将一段程序装配到另一段内存中,如果使用短转移指令,程序复制到任意位置,在进行短转移指令时,都可以正确的找到在源代码中标号标记的位置,而不会出现错误。 + +### 9.10 编译器对转移位移超界的检测 + +如果转移范围超过了转移指令的限制(`jmp short`超过了-127~128,`jmp near ptr`超过了-32768~32767) + +编译器会进行报错。 + +### 实验九 根据材料编程 + +该实验是我放入这个整理的笔记的第一个实验。 + +这个实验的主要作用为传达了一个知识点,要通过汇编在屏幕进行输出,也是通过操作内存。通过向现实缓冲区输入数据可以实现在显示器上显示字符。 + +这个实验值得一做,以加深对于汇编语言本质为内存操作的思想的理解。 + +## 第十章 CALL和RET指令 + +call和ret也都是转移指令。它们经常组合使用,共同用来实现子程序的设计。 + +### 10.1 ret和retf + +ret指令用栈中的数据,修改IP的内容,从而实现近转移。 + +retf指令则用栈中的数据,修改CS和IP的内容,从而实现远转移。 + +如果用汇编语法来解释ret和retf指令: + +```assembly +;ret +pop IP +;retf +pop IP +pop CS +``` + +### 10.2 call指令 + +CPU执行call指令时有两步操作 + ++ 将当前的IP或 当前的CS和IP压入栈中 ++ 转移 + +call指令不能实现短转移(`jmp short`),除此之外和`jmp`相同。 + +### 10.3 依据位移进行转移的call指令 + +`call 标号`是call最基本的用法,相当于进行 + +```assembly +push IP +jmp near ptr 标号 +``` + +对应的机器指令中是目的位置的相对偏移 + +### 10.4 转移的目的地址在指令中的call指令 + +`call far ptr 标号`实现的是段间转移,对应的机器指令中会有目的地址。 + +相当于进行 + +```assembly +push CS +push IP +jmp far ptr 标号 +``` + +### 10.5 转移地址在寄存器中的call指令 + +`call 16位寄存器` + +相当于进行 + +```assembly +push IP +jmp 16位寄存器 +``` + +### 10.6 转移地址在内存中的call指令 + +1. `call word ptr 内存单元地址` + + 相当于进行 + + ```assembly + push IP + jmp word ptr 内存单元地址 + ``` + +2. `call dword ptr 内存单元地址` + + 相当于进行 + + ```assembly + push CS + push IP + jmp dword ptr 内存单元地址 + ``` + +### 10.7 call和ret的配合使用 + +总结以下先前的章节: + +call指令的作用是进行转移,如果转移过程中仅修改IP,就会把IP入栈,如果还会修改CS,就会把CS和IP同时入栈。 + +而ret的作用就是从栈中pop出一个数据,作为IP,跳转回这个位置。 + +retf则会从栈中pop出一个数据作为IP,再pop一个数据作为CS,跳转回这个位置。 + +而这两个指令配合使用,就可以实现子程序的机制。 + +通过call指令调用子程序,保存当前的CS和IP,在子程序的末尾使用ret或retf指令返回主程序。 + +样例: + +```assembly +assume cs:code + +stack segment + db 8 dup (0) + db 8 dup (0) +stack ends + +code segment +start: + mov ax,stack + mov ss,ax + mov sp,16 + mov ax,1000 + call s + mov ax,4c00h + int 21h +s: + ret +code ends + +end start +``` + +使用call和ret的过程中需要注意的就是,如果在子程序中需要使用寄存器,一般也会通过栈的形式暂存原来的寄存器的值,在子程序执行ret指令时手动将其恢复。 + +### 10.8 mul指令 + +mul是乘法指令,使用mul做乘法的时候需要注意以下两点 + ++ 两个相乘的数,要么都是8位,要么都是16位。8位乘法时,一个数默认放在AL中,另一个放在一个8位寄存器或内存字节单元中。16位乘法时,一个数放在AX中,另一个放在16位寄存器或内存单元中。 ++ 8位乘法的结果放在AX中,16位乘法的结果高位放在DX中,低位放在AX中 + +使用格式如下: + +```assembly +mul reg +mul 内存单元 +``` + +### 10.9 模块化程序设计 + +call和ret指令共同支持了汇编语言的模块化设计。在编程过程中,模块化设计是非常常用的,我们可以用简便的方法,实现多个互相联系,功能独立的子程序来解决一个复杂的问题。 + +接下来的内容将探讨一些汇编的子程序设计会遇到的问题和解决思路 + +### 10.10 参数和结果的传递 + +子程序一般都要根据提供的参数来处理一定的事务。处理后将结果提供给调用者。 + +在高级语言中,这两项为参数和返回值,那么在汇编语言就会存在两个问题: + ++ 参数存储在什么地方 ++ 返回值存储在什么地方 + +显然,参数和返回值都可以用寄存器来存储。 + +汇编语言中往往人为选择一个寄存器来存放子程序的参数和返回值,这些内容在风格良好的程序中应当写明在子程序的注释上,如下: + +```assembly +;说明:计算N的三次方 +;参数:(bx)=N +;结果:(dx:ax)=N^3 + +cube: + mov ax,bx + mul bx + mul bx + ret +``` + +### 10.11 批量数据的传递 + +对于先前的例子,参数比较少,可以使用寄存器传递,但如果参数更多,寄存器的数量不够。 + +对于批量的数据,可以把它们放到内存中,然后通过寄存器传递需要处理的数据的地址。 + +此外,除了用寄存器传递参数外,还有一种通用的方法是用栈来传递参数。 + +### 10.12 寄存器冲突的问题 + +在子程序中往往会使用到寄存器,而对寄存器的使用可能会破坏主程序中存储在寄存器的内容。 + +我们希望 + ++ 在编写调用子程序的程序时不必关心子程序到底使用了哪些寄存器 ++ 编写子程序的时候不必关心调用者使用了哪些寄存器 ++ 不会发生寄存器冲突 + +因此解决方法为:在子程序的开始将子程序中所有用到的寄存器的内容保存起来,在子程序返回前恢复。这个过程一般用栈来方便的完成。 + +## 第十一章 标志寄存器 + +CPU内部有一种特殊的寄存器,具有以下三种作用 + ++ 用来存储相关指令的某些执行结果 ++ 用来为CPU执行相关指令提供行为依据 ++ 用来控制CPU的相关工作方式 + +8086CPU中这样的寄存器被称为标志寄存器,其中存储的信息被称为状态字(PSW) + +标志寄存器(以下简称flag)将是学习了解的最后一个寄存器,其中1、3、5、12、13、14、15位在8086CPU中并没有被使用,没有任何含义。 + +![image-20220106103206302](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220106103206302.png) + +### 11.1 ZF标志 + +ZF是flag的第六位,为零标志位。用来记录相关指令执行后,结果是否为0,结果为0时ZF=1。 + +### 11.2 PF标志 + +flag的第二位是PF,奇偶标志位。记录相关指令执行后,结果所有bit位中1的个数是否为偶数。如果1的个数位偶数,pf=1,如果为奇数,pf=0。 + +### 11.3 SF标志 + +flag的第七位是SF,符号标志位,记录相关指令执行后,结果是否为负数,如果结果为负SF=1。 + +大多是运算指令对ZF、PF、SF有影响,例如add,sub,mul,div,inc,or,and等。他们执行后这三个寄存器比较全面的记录了指令的执行结果。 + +### 11.4 CF标志 + +flag的第0位是CF,进位标志位。在进行**无符号数运算**的时候,它记录了运算结果的最高有效位向更高位的进位值,或从更高位的借位值。 + +例如两个8位数据:98H+98H计算,将产生进位。这个进位值就会记录在CF上。 + +同样的,例如97H-98H时向更高位的借位也会记录在CF上。 + +```assembly +mov al,97H +sub al,98H ;执行后(al)=FFH,CF=1 +sub al,al ;执行后(al)=0,CF=0 +``` + +### 11.5 OF标志 + +OF记录了**有符号数**计算结果是否发生了溢出,如果发生溢出,OF=1。 + +要注意CF对无符号运算有意义,OF对有符号运算有意义。它们之间没有关系。 + +### 11.6 adc指令 + +add是带进位的加法指令,它利用了CF位上记录的进位值。 + +`adc ax,bx`实现的功能是(ax)=(ax)+(bx)+CF + +adc指令是用来进行加法的第二步运算的,adc指令和add指令配合就可以对更大的数据进行加法运算。 + +例如计算两个32位数据,就可以先将低16位相加,然后将高十六位和进位值相加。 + +### 11.7 sbb指令 + +sbb是带借位减法指令 + +`sbb ax,bx`相当于实现了(ax)=(ax)-(bx)-CF + +功能使用和adc类似,想要快速理解这两个指令,可以参考竖式的运算。 + +### 11.8 cmp指令 + +cmp指令是是比较指令,相当于减法指令,只是不保存结果,cmp执行后将对标志寄存器产生影响。之后其他相关指令通过识别这些被影响的寄存器位来得知比较结果。 + +例如`cmp ax,ax`就会做一个(ax)-(ax)的运算,但结果不会保存在ax中。之后影响flag的相关位,执行后: + +`zf=1,pf=1,sf=0,cf=0,of=0` + +通过寄存器的值可以看出比较的结果 + +![image-20220106105703936](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220106105703936.png) + +### 11.9 检测比较结果的条件转移指令 + +jcxz是一个已经学习过的条件转移指令,通过检测cx中的数值决定是否转移。 + +而CPU还提供了其他条件转移指令。这些指令和cmp配合,通过查看cmp影响的标志寄存器决定是否转移。 + +![image-20220106105946120](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220106105946120.png) + +### 11.10 DF标志和串传送指令 + +flag的第十位是DF,方向标志位。在串处理指令中,用于控制每次操作后si、di的增减。 + +df=0则每次操作后si和di递增,反之递减。 + +串传送指令举例 + +`movsb` + +执行movsb后,相当于执行以下功能: + +```assembly +mov es:[di],byte ptr ds:[si] ;8086并不支持该指令,只是描述 +如果df=0 +inc si +inc di +如果df=1 +dec si +dec di +``` + +此外还有传送一个字的串传送指令`movsw`,区别就是会将ds:si指向的内存单元中的一个字都送入es:di,自然的,之后根据df标志,si和di会递增2或递减2。 + +### 11.11 pushf和popf + +pushf可以将标志寄存器flag的值压入栈中。 + +popf则可以弹出数据,送入标志寄存器。 + +这两条指令为直接访问标志寄存器提供了一种方法。 + +### 11.12 标志寄存器在Debug中的表示 + +标志寄存器在Debug按照各个标志位单独表示。Debug中表示如下: + +![image-20220106110644594](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220106110644594.png) + +## 第十二章 内中断 + +任意一个通用的CPU,例如8086,都有能力在当前指令执行完毕之后,检测到从CPU外部发送过来的或内部产生的一种特殊信息。这种特殊信息可以称其为中断信息。 + +CPU不在接着刚执行完的指令向下执行,而是会转去处理这个特殊信息。 + +中断信息可以来自于CPU的内部和外部,这一章中将主要讨论来自于CPU内部的中断信息。 + +### 12.1 内中断的产生 + +在8086CPU中,当CPU内部有以下的情况发生的时候,将产生相应的中断信息。 + ++ 除法错误,例如div指令产生的除法溢出 ++ 单步执行 ++ 执行into指令 ++ 执行int指令 + +中断信息的来源简称中断源。上述的4种中断源,在8086CPU中的终端类型码如下 + ++ 除法错误:0 ++ 单步执行:1 ++ 执行into指令:4 ++ 执行int指令:该指令格式为int n,n为字节型立即数,就是提供给cpu的中断类型码。 + +### 12.2 中断处理程序 + +CPU收到中断信息后,需要对中断信息进行处理,如何处理则由编程决定。编写的用来处理中断信息的程序被称为中断处理程序。一般来说,要对不同的中断信息编写不同的处理程序。 + +根据CPU的设计,中断类型码的作用就是用来定位中断处理程序。 + +### 12.3 中断向量表 + +CPU用8位的中断类型码通过中断向量表找到相应的中断处理程序的入口地址。 + +中断向量表在内存中保存。其中存放着256个中断源所对应的中断处理程序入口。 + +![image-20220106120742576](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220106120742576.png) + +对于8086CPU,内存0000:0000到0000:03FF的1024个单元中存放着中断向量表。8086CPU始终从此处读取中断向量表。 + +### 12.4 中断过程 + +8086CPU在收到中断信息后,将引发如下的中断过程: + +1. 从中断信息中取得中断类型码 +2. 标志寄存器的值入栈(因为中断过程需要改变标志寄存器的值,因此先将其保存在栈中) +3. 设置标志寄存器第八位TF和第九位IF值为0,目的后面介绍 +4. CS内容入栈 +5. IP内容入栈 +6. 从内存地址为中断类型码\*4和中断类型码\*4+2的两个字单元中读取中断处理程序的入口地址,设置IP和CS + +### 12.5 中断处理程序 + +中断处理程序必须一致储存在某段内存空间中,而中断处理程序的入口,即中断向量,必须储存在对应的中断向量表表项中。 + +中断处理程序的编写方法和子程序类似: + ++ 保存用到的寄存器 ++ 处理中断 ++ 恢复用到的寄存器 ++ 用iret指令返回 + +iret指令的功能用汇编语法描述为: + +```assembly +pop IP +pop CS +popf +``` + +iret通常和硬件自动完成的中断过程配合使用。 + +### 12.6 除法错误中断的处理 + +CPU在指定div等除法指令的时候,如果发生了除法溢出错误,将产生中断类型码为0的中断信息。 + +系统对引发的0号中断默认的中断处理程序功能为:显示提示信息“Divide overflow"后,回到操作系统中。 + +### 12.7-12.10 编程处理0号中断 + +这几个章节展示了一个过程,编写在屏幕上显示错误信息的程序,将这段程序放入内存中的一个位置,修改中断向量,以达到自定义中断处理程序来处理0号中断的效果,具体内容可以查看课本。这段内容可以加深对于中断处理过程的理解。 + +### 12.11 单步中断 + +CPU在执行完一条指令后,如果检测到标志寄存器的TF位为1,就会产生单步中断,引发中断类型码为1的中断过程。 + +Debug就是利用单步中断,在执行完一条指令后去停止。 + +这也是为何在中断过程中会有将TF置为0这个步骤。 + +### 12.12 响应中断的特殊情况 + +有些情况下,CPU在执行完当前指令后,即使发生中断,也不会响应。 + +举例:如果设置SS和设置SP的指令连续存放,在这之间CPU不会引发中断过程。因为这两条指令必须都执行才能保证指向正确的栈顶。 + +## 第十三章 int指令 + +使用int指令可以调用任何一个中断的处理程序。BIOS和DOS都有一些中断例程提供给程序员和应用程序,在需要时调用可以方便地实现一些功能。 + +## 第十七章 使用BIOS进行键盘输入和磁盘读写 + ++ int 9 中断例程,处理键盘输入 ++ int 16h,读取键盘缓冲区 diff --git a/docs/ComputerNetwork.md b/docs/ComputerNetwork.md new file mode 100644 index 0000000..c0ff80e --- /dev/null +++ b/docs/ComputerNetwork.md @@ -0,0 +1,1404 @@ +*written by PeterAlbus,Copyright © 2022 - SHOU 1951123 Hong Wu* + +**注:本文根据《2021秋计算机网络期末考试大纲》编写。 \* 号部分表示不在大纲内** + +写在前面:计算机网络的学习按层次来,是从物理层到应用层,实际到虚拟的过程。而对于对计算机熟悉的人来说,这却是个陌生到熟悉的过程。在学习阶段对物理层往往云里雾里,而到了复习阶段,在每个阶段的学习过程中都应当想象这一部分是在整个流程的什么位置,起到什么作用,对于理解这个科目,很有帮助。 + +# 计算机网络 + +## 第一章 概述 + +### 1.2 互联网概述 + +#### 1.2.1 网络的网络 + +计算机网络由若干个节点(node)以及连接这些节点的链路(link)组成,网络中的节点可以是计算机、集线器、交换机或路由器。 + +网络间还可以通过路由器再互联起来,这就构成了一个覆盖范围更大的计算机网络。这样的网络称为“互连网”(internet)。 + +> 网络把许多计算机连接在一起,而互连网则把许多网络通过路由器连接在一起,与网络相连的计算机常被称为主机(host)。 + +#### 1.2.2 互联网基础结构发展的三个阶段 + +1. 单个网络ARPANET向互连网(internet)发展 + + 1969年ARPANET——第一个分组交换网。之后开始研究多种网络互连的技术,导致了互连网的出现,也是互联网的雏形。 + + 两个类似但意思不同的名词:internet(互连网)和Internet(互联网)。前者是一个通用名词,泛指多个计算机网络互连而成的计算机网络。后者则是专有名词,指全球最大,由众多网络连接而成的特定互连网,采用TCP/IP协议族作为通信的规则。 +2. 建成了三级结构的互联网(Internet) + + 三级网络,分为主干网、地区网和校园网。 +3. 形成了多层次ISP结构的互联网 + + 互联网主干网逐渐走向商业化,若干个商用互联网主干网替代NSFNET,政府开始不负责互联网的运营。 + + ISP:互联网服务提供者/互联网服务提供商。(中国移动、中国电信、中国联通) + + ISP申请大量IP地址,用户向ISP缴纳费用,即可获取IP地址使用权并通过ISP提供的通信线路接入互联网。 + + ISP也分为不同层次:主干ISP、地区ISP和本地ISP + +### 1.3 互联网的组成 + +互联网的拓扑结构从工作方式上看可以分为两大块: + ++ 边缘部分:连接在互联网上的主机组成,用户直接使用,用来进行通信和资源共享 ++ 核心部分:由大量网络和连接网络的路由器组成,为边缘部分提供服务(连通性和交换) + +#### 1.3.1 互联网的边缘部分 + +边缘部分的通信方式(主机上的程序和主机上的程序之间)可分为两大类:客户端-服务器方式(C/S)和对等方式(P2P)。 + +1. Client/Server + + 在互联网上最常用也是最传统的方式。客户(Client)和服务器(Server)是指通信中涉及的两个应用进程。客户是服务请求方,服务器是服务提供方。 + + + 客户程序:需要知道服务器程序的地址,向服务器发起请求 + + 服务器程序:专门用来提供某种服务,可同时处理多个客户端发起的请求。系统启动后不停运行,被动等待监听客户程序发来的请求。 + +2. Peer-to-Peer * + + 对等连接(P2P)是指两台主机通信时并不区分哪台是服务请求方,哪台是服务提供方。两台机器都运行了P2P软件,他们就可以进行平等的通信。 + +#### 1.3.2 互联网的核心部分 + +网络的核心部分是互联网中最复杂的部分,它需要保证互联网的边缘部分的大量主机的连通性。 + +在网络部分起到核心作用的是路由器。路由器是实现分组交换(packet switching)的关键构件,其任务是转发收到的分组。 + +1. 电路交换 * + + 是电话交换机至今仍使用的交换方式。电话机通过交换机连接起来,以在控制电线数量的情况下保证电话机和每一台电话机相连。 + + ![image-20220102132003489](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102132003489.png) + + 电话机经过多次更新换代,内部仍使用分组交换。**交换**(switching)就是按照某种方式动态地分配传输线路地资源。电路交换的方式会在端到端间建立连接,保证双方的通信资源,且在通信期间不会被占用。 + + > 必须经过"建立连接(占用通信资源)->通话(一直占用通信资源)->释放连接(归还通信资源)"三个步骤的交换方式称为电路交换。 + + 但若使用电路交换在计算机网络传输数据,由于计算机数据的突发性,线路的传输效率往往会很低。 + +2. 分组交换 + + 分组交换则使用存储转发技术。一个要发送的较长的报文会被划分为一个个分组进行发送。分组包含首部也就是"包头",包含了如目的地址和源地址等重要控制信息,保证了分组能正确的交付到传输终点。 + + 路由器则是负责转发分组,当路由器收到一个分组时,会先暂时储存,再根据首部以合适的接口转发出去。分组在传输时一段一段地占用通信资源。 + + 分组交换的优点: + + | 优点 | 所采用的手段 | + | ---- | ------------------------------------------------------------ | + | 高效 | 在分组传输的过程中动态分配传输带宽,对通信链路逐段占用 | + | 灵活 | 为每一个分组灵活地选择最合适的转发路由 | + | 迅速 | 以分组作为传送单位,可以不先建立连接就能向其他主机发送分组 | + | 可靠 | 保证可靠性的网络协议,分布式多路由的分组交换网,使网络具有很好的生存性 | + + ![image-20220102133855544](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102133855544.png) + +### 1.6 计算机网络的性能 + +#### 1.6.1 计算机网络的性能指标 + +1. 速率 + + 比特(bit)指一个二进制数字,是信息论中使用的信息量的单位。 + + 网络技术中的速率是指数据的传送速率,也成为数据率或比特率,速率的单位是bit/s + +2. 带宽 + + 带宽(bandwidth)有两种不同的意义 + + + 某个信号具有的频带宽度。单位是赫(千赫、兆赫等)。表示某信道允许通过的信号频带范围就成为该信道的带宽。 + + 计算机网络中,带宽表示网络中某通道传送数据的能力,网络带宽表示的是单位时间内网络中某信道能通过的“最高数据率”。单位是数据率的单位bit/s。 + + 前者为频域称谓,后者为时域称谓,其本质是相同的,一条通信链路的带宽越宽,其传输的最高数据率也越高。 + +3. 吞吐量 + + 吞吐量(throughput)表示在单位时间内通过某个网络(或信道、接口)的实际的数据量。用于对现实世界网络的一种测量。 + +4. 时延 + + 时延(delay/latency)是指数据从网路一端到另一端所需的时间。有时也称为延迟或迟延。时延有几个不同的部分组成: + + + 发送时延:主机或路由器发送数据帧所需要的时间。发送时延与发送的帧长成正比,与发送速率成反比。 + $$ + 发送时延=\frac{数据帧长度(bit)}{发送速率(bit/s)} + $$ + + + 传播时延:是电磁波在信道中传播一定的距离所需要化的时间。只与信号传送的距离有关。 + + + 处理时延:收到分组时花费一定的时间进行处理 + + + 排队时延:等待转发处理的时间 + +5. 时延带宽积 + + 由上面的两个度量:传播时延和带宽相乘得到。单位是bit。表示发送的第一个比特到达终点时,若持续发送,链路中正在传输的比特数。 + + 时延带宽积又称为以比特位单位的链路长度。 + +6. 往返时间RTT + + 往返时间RTT(Round-Trip Time)也是个重要性能指标。因为在许多情况下互联网上的信息是双向交互的。 + +7. 利用率 + + 分为信道利用率和网络利用率。信道利用率指出某信道有百分之几的时间是被利用的(有数据通过)。完全空闲的信道的利用率是零。网络利用率则是全网络的信道利用率的加权平均值。 + + 信道利用率并非越高越好,当网络通信量增大,在网络节点分组进行处理时需要排队等待,网络引起的时延就会增大。以下是网络当前时延D和网络空闲时延D0、利用率U的关系。 + $$ + D=\frac{D_{0}}{1-U} + $$ + 当网络利用率达到50%时,时延就要加倍。信道或网络利用率过高会产生非常大的时延。 + + ![image-20220102141930754](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102141930754.png) + +### 1.7 计算机网络体系结构 + +#### 1.7.1 计算机网络体系 + +计算机网络中两台计算机进行通信,要进行协调相当复杂。通过“分层”的方法,将庞大的问题转为若干的小问题来解决。 + +OSI标准是法律上的国际标准,将计算机分为七层协议的体系架构。而事实上的国际标准则是TCP/IP协议。 + +两种协议的详细架构将在本笔记的1.7.3章节展示。 + +#### 1.7.2 协议与划分层次 + +> 为进行网络中的数据交换而建立的规则、标准或约定称为网络协议。 + +#### 1.7.3 五层协议的体系结构 + +TCP/IP的四层协议在目前得到了较为广泛的应用。但由于其网络接口层基本没有什么内容,在学习计算机网络时往往将其与OSI协议结合,形成五层协议的网络体系结构。 + +![image-20220102143439652](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102143439652.png) + ++ 应用层:应用进程间交互和通信的规则 ++ 运输层:两台主机中进程间的通信提供通用的数据传输服务。主要使用传输控制协议TCP和用户数据报协议UDP。 ++ 网络层:负责为分组交换网上的不同主机提供通信服务。网络层把运输层产生的报文段封装成分组或包进行发送。TCP/IP协议中主要使用IP协议,分组也叫IP数据报。同时网络层还有选择路由的任务。 ++ 数据链路层:数据链路层将网络层交下来的IP数据报封装成帧(frame)。在两个相邻节点的链路上传送帧,每一帧包括数据和必要控制信息。 ++ 物理层:关注如何表示1和0,以及接收方如何识别发来的1和0。 + +![image-20220102144255025](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102144255025.png) + +#### 1.7.4 实体、协议、服务和服务访问点 + +协议是控制两个对等实体进行通信的规则的集合。 + +> 通过协议的控制,两个对等实体的通信使得本层向上层提供服务,而实现本层协议也会用到下一层提供的服务。 + +协议是水平的,而服务是垂直的。 + +#### 1.7.5 TCP/IP的体系结构 + +![image-20220102144755214](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102144755214.png) + +技术的使用是灵活的,互联网使用的协议有时也会发生演变,分层次画出沙漏状的TCP/IP协议族如下图所示。TCP/IP协议可以为各式各样的应用提供服务,也允许IP协议在格式各样的网络构成的互联网上运行。 + +![image-20220102145239179](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102145239179.png) + +## 第二章 物理层 + +### 2.1 物理层的基本概念 + +物理层考虑如何在连接计算机的各式传输媒体上传输数据。 + +### 2.2 数据通信的基础知识 + +#### 2.2.1 数据通信系统的模型 + +当进行通信时,目的是传递**消息**(message),而**数据**(data)则是运输消息的实体。**信号**(signal)则是数据的电气或电磁的表现。 + +信号可分为两大类: + ++ 模拟信号:消息的参数的取值是连续的 ++ 数字信号:消息的参数的取值是离散的 + +#### 2.2.2 有关信道的几个基本概念 + +信道一般用来表示向某一个方向传送信息的媒体。 + +通信的双方信息交互的方式可以有以下三种: + ++ 单向通信:**单工通信**,一个方向的通信,电视广播等 ++ 双向交替通信:**半双工通信**,通信双方都可以发送和接收,但不能同时发送 ++ 双向同时通信:**双工通信**,双方可以同时发送和接收消息 + +常用编码方式: + +![image-20220102151255099](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102151255099.png) + ++ 不归零制 ++ 归零制 ++ 曼彻斯特编码:位周期中心向上跳变表示0,向下跳变表示1 ++ 差分曼彻斯特编码:位中心始终跳变,每一位开始时有跳变代表0,无跳变代表1。 + +曼彻斯特编码具有自同步能力,不需要时钟信号。 + +带通调制方法: + ++ 调幅AM:载波的振幅变化 ++ 调频FM:载波的频率变化 ++ 调相PM:初始相位变化 + +#### 2.2.3 信道的极限容量 + +> 码元传输的速率越高,或信号传输的距离越远,或噪声干扰越大,或传输媒体质量越差,在接收端波形的失真就越严重。 + +限制码元在信道上传输速率的因素有两个: + +1. 信道能通过的频率范围 + + 信道的频带越宽,能通过的信号高频分量多,就可以用更高的速率传送码元而不出现码间干扰。 + +2. 信噪比 + + 信噪比就是信号的平均功率和噪声的平均功率之比。常记为S/N,用分贝(dB)作为度量单位。(S:信道内信号平均功率,N:高斯噪声功率) + $$ + 信噪比(dB)=10 \log_{10}(S/N) + $$ + 香农公式,信道的极限传输速率C为(W:信道带宽,单位hz): + $$ + C=W \log_2(1 + S/N)(bit/s) + $$ + +### 2.3 物理层下面的传输媒体 + +传输媒体可分为两大类 + ++ 导引型传输媒体 + + 双绞线 + + 同轴电缆 + + 光缆 ++ 非导引型传输媒体 + + 短波通信 + + 无线电微波通信 + + 卫星通信 + + 红外通信、激光通信(近距离) + +### 2.4 信道复用技术 + +#### 2.4.1 频分复用、时分复用和统计时分复用 + ++ 频分复用FDM:最基本的复用之一。用户在分配到一定的频带后,自始至终都占用这个频带。频分复用的所有用户在同样的时间内占用不同的带宽资源。 ++ 时分复用TDM:也是最基本的复用之一。将时间分为一段段等长的时分复用帧。每一个时分复用的用户占用固定序号的时间间隙。 + +![image-20220102153631507](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102153631507.png) + ++ 统计时分复用STDM:解决互联网的突发性问题,改进时分复用,能明显提高信道的利用率。通过集中器集中用户的数据发往高速线路。每个时隙由于不固定分配,需要有用户的地址信息。 + +#### 2.4.2 波分复用 + +波分复用WDM就是光的频分复用。使用一根光纤传输多个光载波信号。现在能复用的路数越来越多,又使用了密集波分复用DWDM这一名词。 + +#### 2.4.3 码分复用 + +码分复用CDM是另一种共享信道的方法,各用户使用不同码型,最初用于军事通信,有很强的抗干扰能力。 + +每个比特时间划分为m个短的间隔,被称为码片。每个站会被指派一个m bit的码片序列。发送时该序列代表1,反码代表0。 + +每个站被分配的码片序列都必须正交,即规格化内积为0。 + +码片向量和本身规格化内积为1,和反码规格化内积为1 + +当接收站接收该站信号时,就用该站码片序列和收到的信号计算规格化内积,结果为1表示1,-1表示0,0表示为其他站发送的信号。 + +### 2.6 宽带接入技术 + +连接到某个ISP以接入互联网的方式。 + +#### 2.6.1 ADSL技术 + +非对称数字用户线ADSL(Asymmetric Digital Subscriber Line)技术是对现有的模拟电话用户需进行改造,把没有被利用的高频部分给用户上网使用。在用户线两端各安装一个调制解调器,采用自适应调制技术选择尽可能高的数据率,不能保证固定的数据率。 + +#### 2.6.2 光纤同轴混合网(HFC网) + +有线电视基础上开发的居民宽带网。 + +#### 2.6.3 FTTx + +x表示不同的光纤接入地点,整个词语表示光纤到xxx + +FTTH即为光纤到户,为理想中的宽带接入方式。(Fiber To The Home) + +## 第三章 数据链路层 + +属于计算机网络的低层,数据链路层使用的信道主要有两种类型:点对点信道和广播信道。 + +主要解决相邻节点的数据传输问题。 + +### 3.1 点对点信道 + +#### 3.1.1 数据链路和帧 + +链路是一条无源的点到点的物理线路段,中间没有任何其他交换节点 + +而数据链路(data link)是另一个概念,除了物理线路,还必须有一些必要的通信协议来控制这些数据的传输。数据链路是链路加上了实现这些协议的软件和硬件。 + +点对点信道数据链路层的协议数据单元为帧。 + +![image-20220102162037404](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102162037404.png) + +#### 3.1.2 三个基本问题 + +1. 封装成帧 + + 在数据前后分别添加首部和尾部(帧定界) + + ![image-20220102162200402](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102162200402.png) + +2. 透明传输 + + 当要传输的数据中出现某些特定的二进制组合时,例如表示帧结束EOT的一串二进制数字,传输会出现错误。为了让这种数据不出现问题,“看不见”有什么会妨碍数据传输,通过字节填充/字符填充(加入转义字符ESC)来解决这种问题。 + +3. 差错检测 + + 通过一些方式解决传输时出现差错的问题。 + + 数据链路层目前广泛使用了循环冗余检验(CRC)的检错技术。在发送的数据后添加n位冗余码。 + + + 发送数据后添加n个0,用其除以一个规定好的除数(除数位数n+1) + + 将余数加到发送数据后 + + 收到每个数据后除以该规定好的除数,其余数为0表示无差错 + +MTU:最大传输尺寸,用来限制每个mac帧的长度 + +### 3.2 点对点协议PPP + +点对点协议PPP(Point-to-Point Protocol)是目前使用的最广泛的数据链路层协议。 + +#### 3.2.1 PPP协议的特点 + +PPP就是用户计算机和ISP通信时使用的数据链路层协议。 + +#### 3.2.2 PPP协议的帧格式 + +![image-20220102164216215](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102164216215.png) + +零比特填充:当使用同步传输时,PPP使用0比特填充实现透明传输。当出现5个连续1的时候,立即填入一个0。接收时相反,发现5个连续1的时候,就把这5个连续1后的0删除。 + +### 3.3 使用广播信道的数据链路层 + +广播信道用于进行一对多的通信 + +#### 3.3.1 局域网的数据链路层 + +当下的以太网在局域网中占据了绝对的优势。以太网几乎成为了局域网的同义词。 + +1. 以太网的两个标准 + + + DIX Ethernet V2 + + IEEE 802.3 + +2. 适配器的作用 + + 计算机与外界局域网的连接是通过通信适配器(adapter)进行的。适配器的重要作用就是串行传输和并行传输的转换。 + +#### 3.3.2 CSMA/CD协议 + +在数据帧的首部写明接收站的地址来在广播特性的总线上实现一对一的通信。 + +以太网采用较为灵活的无连接的工作方式,以太网不对发送的数据编号也不要求发回确认,提供不可靠的交付。而这些工作以及重传等是否进行就交给上层协议,例如tcp协议会完成这些工作。 + +总线上同一时间只能允许一台计算机发送数据,为了进行协调和监控,使用的协议是CSMA/CD,意为载波监听多点接入/碰撞检测。 + +CSMA/CD协议要点: + ++ 多点接入 ++ 载波监听:不管在发送前,还是发送中,每个站都不停地监听信道 ++ 碰撞检测:边发送边监听 + +一旦检测到了碰撞,就要立即停止发送。在碰撞后,最迟经过2倍的端到端传播时延才能被检测到。 + +![image-20220102181925472](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102181925472.png) + +因此以太网的端到端往返时间2r称为争用期,经过争用期还没有检测到碰撞,才能肯定这次发送不会产生碰撞。 + +长度小于争用期发送的字节数(争用期时间*网速)的帧都被认为是无效帧。 + +#### 3.3.3 使用集线器的星形拓扑 + +传统以太网最终发展为使用更便宜和灵活的双绞线。以太网采用星形拓扑,在中心增加了一种名为集线器的设备。双绞线以太网总是和集线器配合使用。 + ++ 集线器使用电子器件来模拟实际电缆线的工作,使用集线器的以太网在逻辑上仍是一个总线网,各站共享逻辑上的总线,使用的还是CSMA/CD协议。同一时刻至多只允许一个站发送数据。 ++ 一个集线器有很多接口。一个集线器很像一个多接口的转发器。 ++ **集线器工作在物理层**,它的每个接口仅仅简单地转发比特,不进行碰撞检测,若两个接口同时有信号输入即发生碰撞,所有的接口都收不到正常的帧。 + +#### 3.3.4 以太网的信道利用率 + +以太网信道被占用的情况包括争用期发生碰撞的情况,如下图所示: + +![image-20220102183433665](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102183433665.png) + +因此要提升以太网的信道利用率,就必须减小r与T0之比。这个比值越打,表名争用期所占的比例越大,每一次碰撞都浪费了不少信道资源。 + +#### 3.3.5 以太网的MAC层 + +> 在局域网中,硬件地址又被称为物理地址或MAC地址。 + +IEEE802标准为局域网规定了一种48位的全球地址,是指局域网上的每一台机器固化在适配器的ROM中的地址。 + +如果连接在局域网上的主机或路由器有多个适配器,那么就有多个地址。准确的说,这48位“地址”是某个接口的标识符。 + +网络上收到一个MAC帧首先检查MAC帧中的目的地址,只收下发往本站的帧。“发往本站的帧”包括三种: + ++ 单播帧:一对一,地址与本站硬件地址相同 ++ 广播帧:一对全体,全1地址 ++ 多播帧:一对多,发送给一部分站点 + +所有的适配器都至少应当能识别前两种帧。 + +### 3.4 扩展的以太网 + +许多情况下希望扩展以太网的覆盖范围,可以在物理层扩展,也可以在数据链路层扩展。扩展后的以太网在网络层仍被视为一个网络。 + +#### 3.4.1 物理层扩展以太网 + ++ 光纤和一对光纤调制解调器 ++ 使用多个集线器连接成覆盖更大范围的多级星形结构的以太网 + +会扩大以太网的碰撞域。 + +#### 3.4.2 数据链路层扩展以太网 + +最初使用网桥 + +1990年,交换式集线器(switching hub)问世,常称为以太网交换机(switch)或第二层交换机,**工作在数据链路层**。 + +1. 以太网交换机的特点 + + 实质上就是一个多接口的网桥。以太网交换机的每个接口都直接与一个单台主机或另一个以太网交换机相连,一般都工作在全双工方式。相互通信的主机都是独占传输媒体,无碰撞地传输数据。 + + 交换机能在输出接口繁忙时缓存要发送的帧,以后再发送出去。 + + 交换机是一种即插即用设备,内部的帧交换表是通过自学习算法自动地逐渐建立起来。 + + 以太网交换机的性能远远超过普通的集线器。 + +2. 从总线以太网到星形以太网 + + 集线器代替了总线后,可使用全双工方式工作,也不再需要CSMA/CD协议,但仍称作以太网,因为它的帧结构仍未改变。 + +### 3.5 高速以太网 + +#### 3.5.1 100BASE-T高速以太网 + +100BASE-T是在双绞线上传送100Mbit/s基带信号的星形拓扑以太网。仍使用IEEE的802.3的CSMA/CD协议。 + +## 第四章 网络层 + +### 4.1 网络层提供的服务 + +问题:在计算机通信中,可靠交付是否应当由网络层提供? + +**面向连接**:两台计算机进行通信时,应当先建立连接,保证发送的分组不丢失,不重复地到达终点。 + +**无连接**:互联网采用的设计思路,网络层向上只提供简单灵活的,无连接的,尽最大努力交付的数据报服务。网络层不提供服务质量的承诺。 + +### 4.2 网际协议IP + +网际协议IP是TCP/IP体系中两个最主要的协议之一。使用的版本有IPv4和IPv6。 + +与IP配套使用的还有三个协议: + ++ 地址解析协议ARP(Address Resolution Protocol) ++ 网际控制报文协议ICMP(Internet Control Message Protocol) ++ 网际组管理协议IGMP(Internet Group Management Protocol) + +![image-20220102191757773](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102191757773.png) + +#### 4.2.1 虚拟互连网络 + +不同的网络想要连接起来非常复杂,会遇到许多问题。将网络连接起来需要使用一些中间设备,根据中间设备所在二点层次,可以有以下四种不同的中间设备。 + ++ 物理层使用的中间设备叫转发器(repeater) ++ 数据链路层使用的中间设备叫网桥或桥接器(bridge) ++ 网络层使用的中间设备叫路由器(router) ++ 在网络层以上使用的中间设备叫网关(gateway) + +转发器和网桥仅仅是扩大一个网络,从网络层看,这仍是一个网络。网关则比较复杂。 + +网络互连时,都是用路由器进行。 + +路由器其实是一台专用计算机,用来在互联网中进行路由选择。 + +**直接交付**指目的主机就在本网络中,而**间接交付**则指通过查找路由表,先把数据包间接交付给路由器,路由器再继续寻址。 + +![image-20220102192708579](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102192708579.png) + +#### 4.2.2 分类的IP地址 + +在TCP/IP协议中,IP地址是一个最基本的概念。 + +1. IP地址及其表示方法 + + 整个互联网就是一个单一的,抽象的网络,IP地址就是给互联网上的每一台主机或路由器的每一个接口分配一个在全世界范围内唯一的32位标识符。IP地址现在由ICANN进行分配。 + + IP地址的编址经历了3个阶段:分类的IP地址,子网的划分和构成超网。 + + 所谓分类的IP地址就是将IP地址划分位若干个固定类,每一类地址都由固定长度的网络号和主机号组成。 + + 网络号在互联网范围内应当是唯一的,主机号在网络号指明的网络范围内是唯一的,因此整个IP地址在互联网范围内应当是唯一的。 + + ![image-20220102193517957](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102193517957.png) + + ABC3类地址较为常用: + + ![image-20220102193628173](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102193628173.png) + +#### 4.2.3 IP地址与硬件地址 + +物理地址是数据链路层和物理层使用的地址,而IP地址是网络层和以上各层使用的地址。 + +![image-20220102194805436](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102194805436.png) + +#### 4.2.4 地址解析协议ARP + +解决问题:主机或者路由器如何知道应当在MAC帧的首部填入什么样的硬件地址? + +ARP的作用:从网络层使用的IP地址,解析出在数据链路层使用的硬件地址。 + +要点 + ++ 地址解析ARP在主机的ARP高速缓存中存放一个从IP地址到硬件地址的映射表,并且这个映射表还经常动态更新。 + ++ 当主机A向B发送数据报时,如果ARP缓存内有B的IP地址,就查出对应硬件地址。如果没有,就会广播一个ARP请求分组,原理如下图。 + + ![image-20220102195450227](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102195450227.png) + ++ ARP缓存的内容都有一个生存时间,以避免硬件的更改。 + +#### 4.2.5 IP数据报的格式 + +![image-20220102195641806](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102195641806.png) + + + +IP数据报的各个字段: + ++ 版本:通信双方使用的版本必须一致(ipv4,ipv6) ++ 首部长度 ++ 区分服务,一般情况下都不使用 ++ 总长度:理论最大长度为65535字节,实际中不可超过数据链路层规定的MTU值 ++ 标识:超过MTU而分片时使用 ++ 标志:占3位但仅仅有两位有意义,最低位MF=1表示后面还有分片,中间为DF=0表示允许分片 ++ 片偏移:以8个字节为偏移单位 ++ 生存时间(TTL):Time to Live,表明数据包在网络中寿命,路由器每跳转一次,TTL减一,防止无法到达的数据包在网络中兜圈子。最大数值255。设置TTL为1,表名该数据报仅在局域网中传输。 ++ 首部检验和 ++ 源地址 ++ 目的地址 + +IP数据报首部还有段可变部分,用于增加功能,但很少使用。 + +#### 4.2.6 转发分组流程 + +![image-20220102200546016](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102200546016.png) + +**默认路由**:减少路由表所占空间和搜索路由表的时间。在一个网络只有很少的对外连接时很好用。 + +### 4.3 划分子网和构造超网 + +#### 4.3.1 划分子网 + +1. 从两级IP地址到三级IP地址 + + 在IP地址中增加了一个子网号字段,这种做法叫划分子网(subnetting) + + + 一个拥有很多物理网络的单位,可将所属的物理网络划分为若干个子网,这个单位对外仍表现为一个网络。 + + 划分子网的方法是从主机号借用若干位作为子网号,主机号减少相应位数。 + +2. 子网掩码 + + 通过子网掩码与IP地址按位与得到划分的子网的地址。 + + 使用对应类地址的默认子网掩码与IP地址按位与,应当得出该IP的网络地址 + + **子网掩码是一个网络或一个子网的重要属性** + +#### 4.3.2 分组转发 + +![image-20220102201328744](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102201328744.png) + +#### 4.3.3 无分类编址CIDR(构造超网) + +无分类域间路由选择CIDR(Classless Inter-Domain Routing) + ++ CIDR消除了ABC类地址和划分子网的概念,IP地址回到两级编址,分为网络前缀和主机号 ++ CIDR记法/斜线记法,标记网络前缀所占的位数 ++ CIDR的32位地址掩码,一串1就是网络前缀位数,剩余部分为一串0 ++ 一个单位划分到一个CIDR地址块,仍可以分出子网,网络前缀位数增加 + +CIDR在路由匹配时,使用最长前缀匹配。 + +### 4.4 网际控制报文协议ICMP + +ICMP(Internet Control Message Protocol)允许主机或路由器报告差错情况。ICMP报文作为IP数据包的数据发送。 + +#### 4.4.1 ICMP报文的种类 + +ICMP分为ICMP差错报告报文和ICMP询问报文 + +![image-20220102202328039](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102202328039.png) + +#### 4.4.2 ICMP的应用举例 + +重要应用:分组网间探测PING(Packet InterNet Groper),用来测试两台机器之间的连通性。 + +PING是应用层直接使用网络层的一个例子,没有经过TCP或UDP。 + +另一个应用:traceroute(linux)/tracert(windows),得到目的主机的路由信息 + +### 4.5 互联网的路由选择协议 + +#### 4.5.1 基本概念 + +1. 理想算法 + + 正确、完整、计算简单、能适应网络拓扑变化、稳定、公平、最佳。 + + 静态选择:人工配置,小规模。 + + 动态选择:自适应 + +2. 分层次的路由选择 + + 把互联网分为许多较小的**自治系统**(autonomous system)。一个AS对其他AS表现出的是一个单一的和一致的路由选择策略。 + + 一个大的ISP就是一个自治系统,路由选择协议划分为两大类: + + + 内部网关协议IGP(Interior Gateway Protocol) 自治系统内部使用,RIP、OSPF + + 外部网关协议EGP(External Gateway Protocol) 自治系统之间使用 + +#### 4.5.2 内部网关协议RIP + +1. 工作原理 + + 分布式的基于距离向量的路由选择协议。 + + 每一个路由器都维护它到其他每一个目的网络的距离(跳数)的记录。RIP协议中跳数为16时表示不可达,只适用于小型互联网。 + + 三个要点: + + + 仅和相邻路由器交换信息 + + 交换的信息是当前本路由器所知道的全部信息,即现在的路由表 + + 按固定时间间隔交换路由信息 + +2. 距离向量算法 + + ![image-20220102203651355](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102203651355.png) + +实现简单、开销较小 + +#### 4.5.3 内部网关协议OSPF + +1. 基本特点 + + OSPF(Open Short Path First)开放最短路径优先,是为克服RIP的缺点(坏消息传的慢)开发出来的。实现较为复杂。使用了Dijkstra提出的最短路径算法。 + + 三个要点: + + + 向本自治系统所有路由器发送信息(洪泛法 flooding) + + 发送的信息是与本路由器相邻的所有路由器的链路状态 + + 链路状态发生变化时才发送此信息 + + 互联网规模大时,比RIP好的多。 + +#### 4.5.4 外部网关协议BGP + +RIP和OSPF在自治系统之间由于规模大、性能不定等原因不合适。 + +因此,BGP力求寻找一条能够到达目的网络且比较好的路由,而不需要找最佳路由。 + +采用了路径向量(path vector)路由选择协议。 + +### 4.6 IPv6 + +IPv6使用了更大的地址空间,从32位扩充到128位,在可预见的将来不会用完 + +#### 4.6.2 IPv6的地址 + +分为单播、多播和任播。任播的终点是一组计算机,但只交付其中一个。 + +每个IPv6地址站128位,使用冒号十六进制记法使地址简洁些。 + +**零压缩**:一串连续的0可以用两个连续的冒号替代,但一串地址仅能使用一个零压缩。 + +### 4.8 虚拟专用网VPN和网络地址转换NAT + +#### 4.8.1 虚拟专用网VPN + +三个专用地址,互联网中的路由器不会转发: + +![image-20220102205307827](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102205307827.png) + +利用公用的互联网作为本机构各个专用网间的通信载体,这样的专用网称之为虚拟专用网。 + +#### 4.8.2 网络地址转换NAT + +专用网连接到互联网的路由器上装上NAT软件,NAT路由器有一个全球IP地址,会在通过互联网时进行转换。通过NAT路由器轮流使用有限数量的全球IP地址。 + +现在常用的NAT转换表会把端口号也用上,使得多个主机共用一个NAT路由器上的全球IP地址。 + +## 第五章 运输层 + +### 5.1 运输层协议概述 + +#### 5.1.1 进程之间的通信 + +运输层向上面的应用层提供服务,属于面向通信的最高层,也是用户功能中的最低层。 + +#### 5.1.2 运输层的两个主要协议 + +运输层的两个协议都是互联网的主要标准: + +1. 用户数据报协议UDP(User Datagram Protocol):不需要事先建立连接 +2. 传输控制协议TCP(Transmission Control Protocol):提供面向连接的服务 + +#### 5.1.3 运输层的端口 + +在运输层使用**协议端口号**(protocol port number)来解决报文要传输给哪个进程的问题。 + +通常简称端口,把传送的报文交到目的主机的合适的端口,剩下的工作由TCP或UDP来完成。 + +16位的端口号允许有65535个不同的端口号。 + +运输层端口号分为以下两类: + +1. 服务器端使用的端口号 + + 1. 熟知端口号(0-1023),这些端口号指派给了一些最重要的应用程序,让所有的用户都知道。 + + ![image-20220102215601577](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102215601577.png) + + 2. 登记端口号(1024-49151),为没有熟知端口号的应用程序使用 + +2. 客户端使用的端口号,49152-65535,客户进程运行时才短暂选择 + +### 5.2 用户数据报协议UDP + +#### 5.2.1 UDP概述 + +主要特点: + ++ 无连接的 ++ 尽最大努力交付 ++ 面向报文,发送方的UDP对应用程序交下的报文,既不合并,也不拆分,保留这些报文的边界。 ++ 没有拥塞控制,利于某些实时应用 ++ UDP支持一对一,一对多,多对一和多对多的交互通信 ++ UDP首部开销小,只有8个字节 + +### 5.3 传输控制协议TCP概述 + +#### 5.3.1 TCP主要特点 + ++ TCP是面向连接的运输层协议 + ++ 每一条TCP连接只有两个端点 + ++ TCP提供可靠交付的服务 + ++ TCP提供全双工通信 + ++ 面向字节流,TCP把应用程序交下来的数据仅仅堪称一串无意义的字节流 + + ![image-20220102220250155](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102220250155.png) + + 注:图中的连接是一条虚连接,TCP报文传输到IP层进行处理,而IP是无连接协议,TCP如何实现可靠传输,稍后讨论。 + +#### 5.3.2 TCP的连接 + +TCP连接的端点叫做**套接字(socket)**或插口,端口号拼接到IP地址就构成了套接字。 + +每一条TCP连接唯一地被通信两端的两个端点(即两个套接字)所确定。 + +一个IP地址可以有很多个不同的TCP连接,同一个端口号也可以出现在很多不同的TCP连接中。 + +### 5.4 可靠传输的工作原理 + +TCP采取适当的措施使得两个运输层之间的通信变得可靠。 + +#### 5.4.1 停止等待协议 + +1. 无差错情况 + + 发送报文,收到确认后发送下一条报文 + +2. 出现差错 + + 检测出了差错便丢弃,或者传输错误B未收到,A在超过一段时间没有收到确认,便会自动重传 + + ![image-20220102221229455](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102221229455.png) + +3. 确认丢失和确认迟到 + + 若发送的确认信息丢失或是迟到,A将重新发送该分组,此时B将丢弃重复分组,并仍然向A发送确认。 + + 上述这种可靠传输协议称为自动重传请求ARQ(Automatic Repeat reQuest) + +4. 信道利用率 + + 停止等待协议很简单,但信道利用率很低。当往返时间RTT远大于分组发送时间时,信道利用率会非常低。出现重传还将进一步下降。 + + 为了解决该问题使用流水线传输提高传输效率,会使用**滑动窗口协议**和**连续ARQ协议**。 + +#### 5.4.2 连续ARQ协议 + +最基本的概念:发送方将维持一个发送窗口,发送窗口内的n个分组都可连续发送出去。 + +发送方每收到一个确认,就把发送窗口向前滑动一个位置。 + +接收方则一般使用累计确认,对按序到达的最后一个分组发送确认, + +而如果发送5个分组,第三个分组丢失了,接收方只会对第二个分组发出确认,后面的三个分组都会进行重传,这个情况就叫做Go-back-N(回退N)。 + +### 5.5 TCP首部 + +![image-20220102222137034](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220102222137034.png) + +字段: + +1. 源端口和目的端口 + +2. 序号:字节流中每一个字节都按顺序编号 + +3. 确认号:**期望收到对方下一个报文段的第一个数据字节的序号** + +4. 数据偏移 + +5. 保留 + +6. 紧急URG,通知报文段有紧急数据,优先传送 + +7. 确认ACK,仅当ACK=1时确认号才有效。建立连接后所有报文段都必须把ACK置1 + +8. 推送PSH,尽快交付,很少使用 + +9. 复位RST,RST=1时,连接出现错误,需要释放连接 + +10. 同步SYN,连接建立时用于同步序号 + +11. 终止FIN,释放连接用 + +12. 窗口:发送本报文段一方的接收窗口大小,是发送方设置发送窗口大小的依据 + +13. 检验和 + +14. 紧急指针 + +15. 选项:长度可变,最长40字节 + + 最初规定了一种选项:MSS最大报文段长度(Maximum Segment Size),是**数据字段**的最大长度 + + MSS应尽可能大,保证IP层不需再分片即可 + +### 5.6 TCP可靠传输的实现 + +#### 5.6.1 以字节为单位的滑动窗口 + +- TCP 的滑动窗口是以字节为单位的。 +- 发送方 A 和接收方 B 分别维持一个发送窗口和一个接收窗口。 +- 发送窗口表示:在没有收到确认的情况下,可以连续把窗口内的数据全部发送出去。 +- 接收窗口表示:只允许接收落入窗口内的数据。 + +![image-20220103084028901](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220103084028901.png) + +A收到B的确认号落在发送窗口内,A就可以使发送窗口向前滑动。 + +发送窗口通常只是发送缓存的一部分,发送缓存和发送窗口的前沿应当是重合的。 + +对于不按序到达的数据TCP未明确规定如何处理,丢弃的处理方式价位方便。 + +#### 5.6.2 超时重传时间的选择 + +TCP采用了一种自适应算法,它记录一个报文段发出的时间,以及收到相应的确认的时间。这两个时间差就是报文段的往返时间RTT。TCP会保留一个加权平均RTT,每次收到新的RTT,计算如下: +$$ +新的RTT_S=(1-\alpha) \times (旧的RTT_S)+ \alpha \times (新的RTT样本) +$$ +当$\alpha$接近0时,RTT更新较慢,反之更新较快。 + +超时重传时间RTO(RetransmissionTime-Out)应略大于加权平均往返时间。RFC 6298建议使用下式计算: +$$ +RTO=RTT_S+4 \times RTT_D(RTT偏差的加权平均值) +$$ +在计算RTT时往往会遇到很多困难,例如如何判断响应是对于刚开始发送的报文还是超时重传的报文。 + +解决方案:报文段重传了就不采用样本/每重传一次,就把RTO增大一些。 + +### 5.7 TCP的流量控制 + +#### 5.7.1 利用滑动窗口实现流量控制 + +> **流量控制**(flow control):控制发送方的发送速率,让接收方来得及接收。 + +保证发送方的发送窗口不能超过接收方给出的接收窗口的数值。 + +当rwnd=0时,发送方不会再发送数据,直到接收方重新发送一个新的窗口数值。 + +如果持续不收到新的窗口数值,就会发送一个零窗口探测报文段,对方会确诊这个报文段时给出窗口数值。 + +### 5.8 TCP的拥塞控制 + +#### 5.8.1 拥塞控制的一般原理 + +> 在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种情况就叫做**拥塞**(congestion)。 + +拥塞控制就是防止过多的数据注入到网络中,使网络中的路由器或链路不致过载。 + +![image-20220103091439425](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220103091439425.png) + +#### 5.8.2 TCP的拥塞控制方法 + +TCP有四种拥塞控制算法:慢开始(slow-start)、拥塞避免(congestion avoidance)、快重传(fast retransmit)、快恢复(fast recovery)。 + +发送方控制一个拥塞窗口(CWND),发送方让自己的发送窗口等于拥塞窗口 + +1. 慢开始和拥塞避免 + + 慢开始:从小到大增加拥塞窗口数值 + + 每收到一个报文的确认,拥塞窗口可以增加最多SMSS(最大报文段)的数值 + + 每经过一个传输轮次,拥塞窗口就加倍。 + + ![image-20220103092211946](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220103092211946.png) + + 为了防止cwnd增长过快,设置一个**慢开始门限**ssthresh,当cwnd>ssthresh时,停止使用慢开始算法,转而使用拥塞避免算法。 + + 拥塞避免算法使得cwnd缓慢增大,每经过一个cwnd+1,在这个阶段有加法增大的特点。 + + ![image-20220103092723289](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220103092723289.png) + + 当cwnd=24时出现超时,拥塞避免算法会把ssthresh置为当前cwnd的一半12,同时设置cwnd=1,重新进入慢开始阶段。 + +2. 快重传 + + 快重传要求接收方收到数据立即发送确认,收到失序报文段也发送已收到报文段的重复确认。发送方一旦收到三个重复确认,就会立即重传丢失的报文段。这样就不会出现超时。 + +3. 快恢复 + + 当发送方执行了快重传,知道只是丢失了个别报文段,执行快恢复算法,调整门限值和拥塞窗口都为当前拥塞窗口的一半(ssthresh=cwnd/2,cwnd=ssthresh) + +发送窗口的上限值为接收窗口和拥塞窗口中较小的一个。(Min[rwnd,cwnd]) + +在上述的拥塞避免阶段,拥塞窗口按线性规律增大(AI,Additive Increase),乘法减小(MD,Multiplicative Decrease),两者合在一起叫做AIMD算法。 + +#### 5.8.3 主动队列管理AQM * + +在队列长度到达警惕数值时就主动丢弃到达分组。 + +### 5.9 TCP的运输连接管理 + +#### 5.9.1 TCP的连接建立 + +TCP建立连接的过程叫做握手,握手需要在客户和服务器之间交换3个TCP报文段。 + +![image-20220103093935713](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220103093935713.png) + +三握手:防止已失效的连接请求报文突然又传到B + +#### 5.9.2 TCP的连接释放 + +![image-20220103094236005](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220103094236005.png) + +A发送关闭报文后,B发送确认,但此时连接仅处于半关闭状态,B仍可向A发送数据。 + +B再向A发送释放报文段,确认号和上次确认关闭的确认号相同,等待A确认后关闭,A经过2MSL(最长报文段寿命)关闭。 + +## 第六章 应用层 + +### 6.1 域名系统DNS + +#### 6.1.1 域名系统概述 + +> **域名系统**DNS(Domain Name System)是互联网使用的命名系统,用来把便于人们使用的机器名字转换为IP地址。 + +域名到IP地址的解析是由分布在互联网上的许多域名服务器程序共同完成的。应用程序需要解析主机名时,就调用解析程序,解析程序把待解析的域名放在DNS请求报文中,以UDP用户数据报的方式发送给本地域名服务器。本地域名服务器把查找到的对应的IP地址返回。 + +#### 6.1.2 互联网的域名结构 + +每一个域名都由一个**标号**(label)序列组成。而各标号之间用点隔开。 + +![image-20220103095512725](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220103095512725.png) + +2012年5月的顶级域名已经有326个。 + +顶级域名分为三大类: + ++ 国家顶级域名(cn/us) ++ 通用顶级域名(com/net/org/...) ++ 基础结构域名:只有一个,arpa,用于反向域名解析 + +我国的二级域名分为类别域名和行政区域名。 + +![image-20220103095805811](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220103095805811.png) + +#### 6.1.3 域名服务器 + +**权限域名服务器**保存所管辖的范围内所有主机的域名到ip地址的映射 + ++ 根域名服务器:所有顶级域名的IP地址,全世界已经有588个地点安装了根域名服务器 ++ 顶级域名服务器(TLD服务器):管理该顶级域名服务器下的所有二级域名 ++ 权限域名服务器:可以有很多层,当权限域名服务器还不能给出最后的回答,会告知下一级权限域名服务器的地址 ++ 本地域名服务器:DNS请求最先查看的服务器,如果缓存内有目的地址,就不会再查询根域名服务器 + +主机向本地域名服务器的查询一般是**递归查询**。 + +本地域名服务器向根域名服务器的查询一般是迭代查询。 + +### 6.4 万维网WWW + +#### 6.4.1 万维网概述 + +> 万维网是一个大规模的联机式的信息储藏所。万维网通过链接的方式从一个站点访问到另一个站点 + +![image-20220103100631887](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220103100631887.png) + +万维网使用**统一资源定位符URL**(Uniform Resource Locator)来标识万维网上的各种文档,交互遵循超文本传输协议HTTP(HyperText Transfer Protocol),它是应用层协议,使用TCP连接进行可靠传送。同时,万维网文档使用**超文本标记语言HTML**(HyperText Markup Language)。 + +#### 6.4.2 统一资源定位符URL + +URL的一般形式:<协议>://<主机>:<端口>/<路径> + +若您通过html方式访问本笔记,由于本笔记未部署在默认的80或443端口,地址栏应当就是一个完整的url。 + ++ 使用http的html:http://<主机>:<端口>/<路径>,默认端口号为80时,可省略,若再省略路径,URL就会指向设定的主页。对于本笔记在互联网上部署的站点,省略路径后应当能看到默认的tomcat页面。 + +#### 6.4.3 超文本传输协议HTTP + +面向事务的应用层协议。是无状态的。而如果要包含状态,可使用Cookie。 + +#### 6.4.4 万维网的文档 + +1. 超文本标记语言HTML + + HTML是一种制作万维网页面的标准语言,它消除了不同计算机之间信息交流的障碍。 + + 不是协议,只是一种使用的语言。 + +2. 动态文档 + + 普通的html文档是最基本的一种,即**静态文档**,静态文档存储在万维网服务器中,用户浏览的过程中不会改变。本笔记在网页上的部署就是静态文档。 + + 动态文档则是指用户访问时由应用程序动态创建(例如jsp)。动态文档有报告最新消息的能力。 + +3. 活动万维网文档 + + 活动文档是一种提供屏幕连续更新的技术。对于服务器来说,这是一个静态文档。但在浏览器中活动文档可以在浏览器端运行,典型案例是JavaScript。本笔记的目录就是使用JavaScript在客户端动态生成的。 + +### 6.5 电子邮件 + +> **电子邮件**(e-mail)是互联网上使用的最多和最受用户欢迎的一种应用。电子邮件把邮件发送到收件人使用的邮件服务器,并放在其中的收件人邮箱中。收件人可在自己方便时上网到自己使用的邮件服务器进行读取。 + +![image-20220103102520392](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220103102520392.png) + +邮件地址的格式: + +用户名@邮件服务器的域名 + +用户名在邮件服务器中应当是唯一的。 + +#### 6.5.2 SMTP简单邮件传送协议 + +1. 连接建立 + + 发送方服务器有邮件要发送时,使用SMTP熟知端口25与接收方建立TCP连接。 + +2. 邮件传送 + +3. 连接释放 + +#### 6.5.4 邮件读取协议POP3和IMAP + +邮局协议POP:简单、功能能优先。用户代理运行POP客户端程序,服务器运行服务器程序。用户从服务器读取了邮件,服务器就会将其删除。 + +网际报文存取协议IMAP:建立TCP连接,首先能看到邮件首部,需要打开时才传送到计算机上。且用户若未发出删除邮件的命令,IMAP服务器邮箱的邮件将一直保留。 + +### 6.6 动态主机配置协议DHCP + +为了省去给计算机配置IP地址的麻烦,使用动态主机配置协议(Dynamic Host Configuration Protocol),提供了即插即用联网的机制。 + +计算机连入网络时向DHCP服务器发送发现报文(DHCPDISCOVER),DHCP服务器从数据库查找或分配新的IP地址给机器。 + +每个网络至少会有一个DHCP中继代理(通常是一台路由器),配置了DHCP服务器的IP地址信息,收到请求时向DHCP转发。DHCP分配的IP地址是临时的。 + +## 第七章 网络安全 + +### 7.1 网络安全问题概述 + +#### 7.1.1 计算机网络面临的安全性威胁 + +两大类威胁: + ++ 主动攻击 + + + 篡改 + + + 恶意程序:计算机病毒、计算机蠕虫、特洛伊木马、逻辑炸弹、后门入侵、流氓软件 + + + **拒绝服务DoS**(Denial of Service) + + 攻击者向互联网上的某个服务器不停地发送大量分组,使服务器无法提供正常服务。 + + 若成百上千的网站集中攻击,就称为**分布式拒绝服务DDoS**(Distributed Denial of Service) + ++ 被动攻击:从网络上窃听内容 + +## 附录 练习题解析 + +*本练习解析为笔者本人根据自己学习理解撰写,不保证正确性* + +### 4.10 + +**试辨认以下IP地址的网络类别** + +最容易记的辨认方法:IP地址转换为二进制,第一位为0-A类网络,前两位为10-B类网络,前三位为110-C类网络 + +直接判断十进制需要花费一点时间记忆,但辨认速度大幅提升: + +第一位为0,代表前八位的二进制范围是0000,0000-0111,1111,转换为点分十进制的第一个数字就是0~127。由于127作为本地软件环回测试的地址,0则表示本网络,因此A类地址点分十进制第一个数字为1~126。 + +前两位为10,代表二进制范围是1000,0000-1011,1111,因此第一个数字范围为128~191 + +前三位为110,代表二进制范围是1100,0000-1101,1111,因此第一个数字范围为192~223 + +1. 128-B类地址 +2. 21-A类地址 +3. 183-B类地址 +4. 192-C类地址 +5. 89-A类地址 +6. 200-C类地址 + +### 4.20 + +**设路由器建立了以下路由表,下列五个分组的目的地址分别为:** + +![image-20220109084247494](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220109084247494.png) + +1. 128.96.39.10,经过与子网掩码255.255.255.128与运算,网络号为192.96.39.0,下一跳接口m0 +2. 128.96.40.12,经过与子网掩码255.255.255.128与运算,网络号为192.96.40.0,下一跳R~2~ +3. 128.96.40.151,经过与子网掩码255.255.255.128与运算,网络号为192.96.40.128,下一跳默认路由R~4~ +4. 192.4.153.17,经过与子网掩码255.255.255.192与运算,网络号为192.4.153.0,下一跳R~3~ +5. 192.4.153.90,经过与子网掩码255.255.255.192与运算,网络号为192.4.153.0,下一跳R~3~ + +### 4.24 + +**试找出可能产生以下数目的A类子网的子网掩码(采用连续掩码)** + +主要注意点为该种划分子网方式时:子网号不能为全0或全1,以及是A类子网 + +1. 2 个 + + 子网数目为2,即代表存在2个网络,从主机号内划分n位给子网,2^n^-2=2,n=2 + + 因此子网掩码为1111,1111,1100,0000,0000,0000,0000,0000 + + 即255.192.0.0,产生两个子网,子网号分别为64和128 + +2. 6个 + + 2^n^-2=6,2^n^=8,n=3 + + 子网掩码为1111,1111,1110,0000,0000,0000,0000,0000 + + 即255.224.0.0 + +3. 30个 + + 2^n^-2=30,n=5 + + 子网掩码255.248.0.0 + +4. 62个 + + n=6 + + 子网掩码255.252.0.0 + +5. 122个,该题没有2^n^-2=122的解,只能往大了算,即2^n^=128,n=7 + + 子网掩码255.254.0.0 + +6. 同上 + + 子网掩码255.255.0.0 + +### 4.32 + +**以下的地址前缀哪一个地址与2.52.90.140匹配?** + +1.0/4 2.32/4 3.4/6 4.80/4 + +由于所有的网络前缀都不超过6位<8,因此只要将2转换成二进制0000,0010对比即可,可以看出前6位全为0 + +1. 0000,0000:前四位0000,匹配 + +2. 0010,0000:前四位0010,不匹配 + +3. 0000,0100:前六位0000,01,不匹配 +4. 0101,0000:前四位0101,不匹配 + +### 4.33 + +**下面的前缀中的哪个和地址152.7.77.159和152.31.47.252都匹配?** + +1. 152.40/13 +2. 153.40/9 +3. 152.64/12 +4. 152.0/11 + +首先排除第二个,前八位就不同。其余三个只需对比第二个十进制数字即可 + +7转换为二进制:0000,0111 + +31转换为二进制:0001,1111 + +只有前(8)+3位相同,要同时匹配,子网掩码不能超过8+3=11位,直接得出答案为第四个 + +### 4.34 + +**与下列掩码相对应的网络前缀各有多少位?** + +没什么技巧,二进制有几个1就有几位 + ++ 192.0.0.0:两位 ++ 240.0.0.0:四位 ++ 255.224.0.0:8+3=十一位 ++ 255.255.255.252:3*8+6=三十位 + +### 4.41 + +![image-20220109101629041](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220109101629041.png) + +首先把下一条路由器都置为C,距离+1 + +N~2~ 5 C + +N~3~ 9 C + +N~6~ 5 C + +N~8~ 4 C + +N~9~ 6 C + +遍历该路由表 + +N~2~ 5 C——已有,下一跳同样为C,替换原路由 + +N~3~ 9 C——没有,加入原路由表 + +N~6~ 5 C——已有,下一跳不为C,路径更短,替换原路由 + +N~8~ 4 C——已有,下一跳不为C,路径不变,无操作 + +N~9~ 6 C——已有,下一跳不为C,路径更长,无操作 + +替换后路由: + +![image-20220109102525581](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220109102525581.png) + +### 4.42 + +![image-20220109102331764](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220109102331764.png) + +![image-20220109102341776](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220109102341776.png) + +每一条下一跳置为C,距离+1 + +N~1~ 3 C + +N~2~ 2 C + +N~3~ 4 C + +N~4~ 8 C + +遍历 + +更短,替换原路由 + +同样为C,替换原路由(但距离没有变换) + +更长,无操作 + +更长,无操作 + +![image-20220109102702466](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220109102702466.png) + +### 4.54 + +**某单位分配到一个起始地址为14.24.74.0/24的地址块,该单位需要用到三个子网,它们三个子地址块的要求是:子网N~1~需要120个地址,子网N~2~需要60个地址,子网N~3~需要10个地址** + +需要120个地址,因此主机号需要7位,使用子网14.24.74.0/25 + +第一个子网网段为14.24.74.0-14.24.74.127,任取其中14.24.74.1-14.24.74.126中的120个地址即可 + +需要60个地址,主机号需要6位,使用子网14.24.74.128/26 + +第二个子网网段为14.24.74.128-12.24.74.191,任取14.24.74.129-14.24.74.190中的60个地址分配即可 + +最后一个需要10个地址,主机号需要4位,使用子网14.24.74.224/28 + +第三个子网网段为14.24.74.224-14.24.74.239,任取14.24.74.224-14.24.74.238中的10个地址分配即可 + +### 4.64 + +**把以下IPv6地址用零压缩方法写成简洁形式** + +没什么技巧,就是概念,只写答案了: + +1. ::0F53:6382:AB00:67DB:BB27:7332 +2. ::004D:ABCD +3. ::AF36:7328:0:87AA:0398 +4. 2819:00AF::0035:0CB2:B271 + +### 5.23 + +**主机A向主机B连续发送了两个TCP报文段,其序号分别是70和100,试问:** + ++ **第一个报文段携带了多少个字节的数据** + + 70-99,按字节编址,30个字节 + ++ **主机B收到第一个报文段后发回的确认号应当是多少?** + + 期望收到的第一个字节序号:100 + ++ **如果B收到第二个报文段后发回的确认中确认号是180,试问A发送的第二个报文中数据有多少字节** + + 100-179,80个字节 + ++ **如果A发送的第一个报文段丢失,第二个报文段到达了B,B收到第二个报文段后确认号应该是?** + + 70,仍期望收到第一个报文 + +### 5.38 + +**设TCP的ssthresh的初始值为8(单位为报文段)。当拥塞窗口上升到12时网络发生了超时,TCP使用慢开始和拥塞避免,试分别求出第一轮次到第十五轮次传输的各拥塞窗口大小。说明每次拥塞窗口变化的原因。** + +1. cwnd=1,ssthresh=8//慢开始 + +2. cwnd=2,ssthresh=8 + +3. cwnd=4,ssthresh=8 +4. cwnd=8,ssthresh=8 +5. cwnd=9,ssthresh=8//拥塞避免 +6. cwnd=10,ssthresh=8 +7. cwnd=11,ssthresh=8 +8. cwnd=12,ssthresh=8 +9. cwnd=1,ssthresh=6//超时,门限设为一半,cwnd=1,慢开始 +10. cwnd=2,ssthresh=6 +11. cwnd=4,ssthresh=6 +12. cwnd=8,ssthresh=6//拥塞避免 +13. cwnd=9,ssthresh=6 +14. cwnd=10,ssthresh=6 +15. cwnd=11,ssthresh=6 + +### 5.39 + +![image-20220109145434518](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220109145434518.png) + +1. ![image-20220109145638570](https://file.peteralbus.com/assets/blog/imgs/blogimg/image-20220109145638570.png) +2. 1-6慢开始,23-26慢开始 +3. 6-16和17-22皆为拥塞避免 +4. 16为3ACK,因为cwnd仅减半,没有从1开始 +5. 22为超时,cwnd=1 +6. 第一轮次32,18时已经减半设置为21(16-17时设置),24轮已经设为13(22-23时设置) +7. 第7轮,累加计算即可 +8. cwnd=sstresh=4,设为当前一半 + diff --git a/docs/ComputerOS.md b/docs/ComputerOS.md new file mode 100644 index 0000000..6d92596 --- /dev/null +++ b/docs/ComputerOS.md @@ -0,0 +1,2310 @@ +*written by PeterAlbus,Copyright © 2021 - SHOU 1951123 Hong Wu* + +**注:对于2021年上海海洋大学期末考试来说,打\*的部分不在韩彦岭老师提供的期末复习提纲中(若一个根目录标识了\*号,则所有子目录也不在复习提纲中),但阅读或许有助于加深对操作系统整体的理解。此外,有些部分课本与上课教学顺序并不一致,考虑到课堂教授顺序更符合理解顺序,某些部分可能会重新编号,与课本顺序不同。** + +--- + +# 第一章 操作系统概论 + +> **操作系统**(operation system, OS)是配置在计算机硬件平台上的第一层软件,是管理整个计算机软硬件资源的系统软件。 + +## 1.1 操作系统的概念 + +操作系统是计算机系统中一组控制和管理计算机硬件资源和软件资源,合理地对各类作业进行调度,以方便用户使用的程序的集合。 + +操作系统的主要功能(五大功能): + ++ 处理器管理 ++ 存储器管理 ++ 设备管理 ++ 文件系统 ++ 用户接口 + +## 1.2 操作系统的发展历程 + +> 无操作系统时代→单道批处理系统→多道程序系统→分时操作系统→实时操作系统 + +### 1.2.1 无操作系统时代(1945-1955)* + +程序员采用纸带或卡片记录程序,人工操作,人工I/O。计算机运行速度提高后会导致I/O速度和计算速度极其不匹配。 + +缺点: + ++ 用户独占资源 ++ 人工干预较多 ++ CPU等待人工操作 + +### 1.2.2 单道批处理系统(1955-1965)* + +由监督程序依次将磁盘中的作业调入内存,待作业执行完毕后再把控制权交还给监督程序。 + +严格来说,它只能算作OS的前身而并非是现在人们理解的OS。 + +主要特征: + ++ 自动性 ++ 顺序性 ++ 单道性 + +### 1.3.3 多道程序系统(1965-1980)* + +在该系统中,用户所提交的作业都先存放在外存上并排成一个队列,称为”后备队列“;然后,由作业调度程序按一定的算法从后备队列中选择若干个作业调入内存,使他们共享CPU和系统中的各项资源。 + +### 1.2.4 分时操作系统 + +分时操作系统让用户通过与计算机相连接的终端来使用计算机系统,允许多个用户同时与计算机系统进行一系列交往。(举例:linux系统的计算机可以通过SSH与多个用户同时远程连接,多个用户在不同终端输入指令)系统能快速地对用户提出的请求给予应答,使得每个用户都感到好像各自有一台独立支持自己请求服务的计算机。 + +> 允许多个联机用户同时使用一台计算机进行计算地操作系统称**分时操作系统**(time sharing operating system) + +分时操作系统的四个特点: + ++ 多路性 ++ 独立性 ++ 及时性 ++ 交互性 + +目标:公平、高效 + +### 1.2.5 实时操作系统* + +> **实时操作系统**(real time operating system)是指当数据或事件产生时,能够接受并以足够快的速度处理,其处理的结果又能在规定的时间内来控制生产过程或对处理系统做出快速响应,并控制所有实时任务协调一致运行的操作系。 +> +> 提供及时响应和高可靠性是其特点。 + +特点: + ++ 多路性 ++ 独立性 ++ 及时性 ++ 交互性 ++ 可靠性 + +### 1.2.6 各种操作系统类型极其简介 + ++ 微机操作系统:文件管理,执行程序 ++ 网络操作系统:具备网络接口的传统操作系统 ++ 分布式操作系统:用于管理分布式计算机系统的操作系统 ++ 嵌入式操作系统:在计算机硬件网络上配备的支持应用软件的系统软件是嵌入式操作系统 + +## 1.3 操作系统的基本特征 + +并发性、共享性、虚拟性、异步性。 + +并发性是操作系统最重要的特性。 + +并发性和共享性是操作系统最基本的特征。 + +### 1.3.1 并发性 + +> **并发性**(concurrence)是指两个或两个以上的事件或活动在同一时间间隔内发生。 +> +> (并行:两个/多个事件在同一时刻内发生)。 + +操作系统引入了进程来解决并发问题。 + +### 1.3.2 共享性 + +> **共享**是指操作系统中的资源(包括硬件资源和软件资源)可被多个并发执行的进程共同使用,而不是被一个进程独占。 + +资源共享的方式: + ++ 互斥访问:一段时间只允许一个进程访问。这样的资源被称为临界资源。 ++ 同时访问:同一时间段允许多个进程访问。典型的此类资源:硬盘。 + +### 1.3.3 虚拟性 + +> **虚拟性**是指操作系统中的一种管理技术,它把物理上的一个实体编程逻辑上的多个对应物,或者把物理上的多个实体变成逻辑上的一个对应物的技术。 + +Spooling技术、窗口技术、虚拟存储器...... + +### 1.3.4 异步性 + +> **异步性**也称随机性,是指多道程序环境中多个进程的执行、推进和完成时间都是随机的、交替的不可预测的。 + +操作系统需要考虑异步性问题使结果一致。 + +## 1.4 操作系统的功能 + +五大功能(同1.1):处理器管理。存储器管理。设备管理。文件系统、用户接口 + ++ 处理器管理:引入了进程(线程)的概念,对处理机的管理可归结为对进程/线程的管理。 + + 进程控制 + + 进程同步 + + 进程通信 + + 调度 + + 作业调度:从后备队列中挑选作业分配资源,建立进程,放入就绪队列 + + 进程调度:从就绪队列中挑选进程分配处理机 ++ 存储器管理:为多道程序的运行提供良好的环境,方便用户的使用,提高存储器的利用率。 + + 内存分配 + + 内存保护 + + 地址映射 + + 内存扩充 ++ 设备管理:完成I/O请求,分配I/O设备,提高I/O速度 + + 缓冲管理 + + 数据分配 + + 设备处理 ++ 文件管理:对用户文件和系统文件进行管理,方便用户使用,保证文件的安全性 + + 文件存储空间的管理:分配外存空间 + + 目录管理 + + 文件的读写管理和保护 ++ 用户接口 + + 命令接口(由一组”命令集“组成)、图形接口 + + 程序接口(系统调用/高级语言库函数) + +## 1.5 操作系统的结构设计* + +### 1.5.1 传统的操作系统结构 + ++ 无结构操作系统:逻辑复杂,维护困难 ++ 模块化操作系统:通过分解、模块化控制大型如那件复杂度 ++ 分层式操作系统:有序地分层 + + 自底向上建立若干中间层 + + 可简化设计的复杂度 + + 下层为上层提供服务 + +### 1.5.2 客户、服务机模式 + +### 1.5.3 微内核操作系统 + ++ 足够小的内核 ++ 基于客户/服务器模式 ++ 机制与策略分离 ++ 采用面向对象技术 + +--- + +# 第二章 操作系统接口* + +操作系统(OS)向用户提供了以下两类接口 + ++ 用户接口。支持用户与OS间进行交互 ++ 程序接口,也称应用程序接口API,是为程序员在编程时使用的,系统和应用程序通过这个接口可在执行中访问系统中的资源和取得OS中的服务,它也是程序能取得操作系统服务的唯一途径。 + +--- + +# 第三章 进程管理 + +## 3.1 进程的基本概念 + +**单道程序设计**:程序的执行方式是顺序执行,即必须在一个程序执行完成后,才允许另一个程序执行。 + +**多道程序环境**:允许多个程序并发执行。 + +### 3.1.1 程序的顺序执行及其特征 + +程序内部的顺序性:在处理器上的执行严格有序,即只有在前一个操作结束后,才能进行下一个操作。 + +程序外部的顺序性:完成一个任务若需要若干个程序,这些程序也按照调用次序严格有序执行。 + +特征: + ++ 顺序性 ++ 封闭性 ++ 结果的确定性 ++ 可再现性 + +### 3.1.2 程序的并发执行及其特征 + +当两个操作的执行不互相依赖,则这两个操作之间两个程序可并发执行。 + +程序的并发执行可提高系统吞吐量。 + +对于并发来说,宏观上似乎同一时刻在进行多个进程,实际上同一时刻仍只能进行同一进程(微观上)。 + +特征: + ++ 间断性 ++ 失去封闭性:多个程序共享系统中的各种资源,会使程序的运行受到其他程序的影响 ++ 不可再现性:由于失去了封闭性,两个进程以不同的速度运行,可能出现很多不同的情况。 + +### 3.1.3 进程的定义及描述 + +#### 1.进程的定义 + +> + 非正式:执行中的程序/运行中的代码段 +> + 正式:可并发执行的程序在一个数据集合上的执行过程,是系统进行资源调度和分配的一个独立单位。 + +进程!=程序,程序是静态的,而进程是动态的。 + +#### 2.进程与程序的关系 + +| 进程 | 程序 | +| ---- | ---- | +| 动态 | 静态 | +| 并发 | 顺序 | +| 暂时 | 永久 | + +进程与程序并非一一对应的关系。 + +#### 3.进程出现的动机:支持多道编程 + +#### 4.进程的特征 + ++ 结构特征:进程包含数据集合和运行于其上的程序,它至少由程序块,数据块和进程控制块等要素组成。 ++ **动态性**:进程是程序在数据集合上的一次执行**过程**。程序有其生命周期,由创建而产生,调度而执行,得不到资源而阻塞,撤销而消亡。为进程**最基本的特征**。 ++ **并发性**:没有建立PCB是不能并发执行的。(建立了进程才能并发执行)是**进程的重要特征**,也是OS的重要特征。 ++ **独立性**:进程实体是一个能独立运行,独立分配资源和独立接受调度的基本单位。 ++ **异步性**:也称随机性,是指进程按照各自独立的不可预知的速度向前推进。 + +## 3.2 进程状态及其转换 + +### 3.2.1 进程状态及其转换 + +#### 1.进程的三种基本状态 + ++ 就绪(ready)状态:进程具备运行条件,等待系统分配处理器 ++ 执行(running)状态:进程占有处理器正在运行 ++ 阻塞(blocked)状态:又称为等待(wait)态或者睡眠(sleep)态。正在执行的进程由于发生某事件而无法继续执行,便放弃处理机而处于暂停状态。 + +![三种基本状态的转化](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/os_01.png) + +#### 2.挂起状态(被换出内存的状态) + +引入挂起状态的原因: + ++ 终端用户请求 ++ 父进程请求 ++ 负荷调节需要 ++ 操作系统需要 + +![引入挂起的状态转换](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/os_02.png) + +### 3.2.2 进程控制块(PCB) + +进程的组成:PCB、程序段、数据段、堆栈。 + +引入PCB的作用:使程序成为独立运行的模块,和其他程序并发执行。 + +PCB是实体的一部分,是OS中最重要的数据结构。 + ++ PCB是进程存在的唯一标志。 ++ PCB(Process control block)常驻内存。 + +#### 1.进程控制块中的信息 + ++ 标识信息(进程描述信息) + + 进程名 + + 进程标识符 + + 用户名 ++ 现场信息(处理机状态信息) + + 通用寄存器 + + 指令计数器 + + 程序状态字寄存器 + + 栈指针 ++ 进程调度信息 + + 进程状态 + + 进程优先级 + + 运行统计信息 + + 进程阻塞原因 ++ 进程控制和资源占有信息 + + 进程调度信息 + + 进程组成信息 + + 族系信息 + + 进程间通信信息 + + 进程段/页表指针 + + CPU的占有和使用信息 + + 进程特权信息 + + 资源清单 + +进程控制块的组织方式:链接方式、索引方式 + +## 3.3 进程控制 + +进程管理中对进程的控制是最基本的功能。其控制包括:创建进程,终止已完成进程,状态转换。 + +> **原语**:计算机进程的控制通常由原语完成。所谓原语,一般是指由若干条指令组成的程序段,用来实现某个特定功能,在执行过程中不可被中断。 + +### 3.3.1 进程的创建 + +#### 1.引起进程创建的事件: + ++ 用户登录 ++ 作业调度 ++ 提供服务 ++ 应用请求 + +#### 2.创建过程(Create原语) + ++ 申请空白PCB ++ 为新进程分配资源 ++ 初始化PCB + + 进程描述信息 + + 处理机状态信息 + + 初始化进程控制信息 ++ 将进程插入就绪队列 + +### 3.3.2 进程的终止(原3.3.3) + +#### 1.引起进程终止的事件: + ++ 正常结束:HALT,logoff ++ 异常结束:越界、非法、I/O等 ++ 外界干预:管理员kill等 + +#### 2.进程的终止过程: + ++ 检查进程状态 ++ 执行态->终止,且置调度标志位真 ++ 检测有无子孙需终止 ++ 归还资源给父进程或系统 ++ PCB队列中移出被终止进程 + +### 3.3.3 进程的阻塞与唤醒(原3.3.2) + +#### 1.引起进程阻塞与唤醒的事件 + ++ 请求系统服务而得不到满足 ++ 启动某种操作(如I/O)操作 ++ 新的数据尚未到达 ++ 无新工作可做 + +#### 2.进程阻塞过程(block原语) + +是进程自身的一种主动行为 + ++ 停止进程执行,保存相关信息到PCB。 ++ 修改PCB的相关内容,如修改进程状态为等待(阻塞) ++ 加入阻塞队列 ++ 转入进程调度程序,调度其他进程运行 + +#### 3.进程唤醒过程(wake up原语) + ++ 从阻塞(等待)队列取出PCB ++ 修改PCB的相关信息,如进程状态修改为就绪 ++ 把修改后的PCB加入有关就绪进程队列 + +### 3.3.4 进程的挂起与激活 + +suspend-active 原语 + +阻塞、唤醒一般由OS实现,而挂起、激活可以由用户实现 + +## 3.4 线程(原3.7) + +公平和效率的权衡是进程管理永恒的话题。 + +进程的缺陷: + ++ 一个进程在一个时间只能做一个事情 ++ 阻塞将使进程挂起,使整个进程都无法执行 + +为了解决以上问题: + +> 线程(threads),比进程更小的能独立运行的基本单位, + +人们通过线程,试图提高系统内程序并发执行的速度,从而进一步提高系统的吞吐量。 + +### 3.4.1 线程的引入 + +单线程结构的进程给并发程序设计带来了一系列的问题: + ++ 进程时空的开销大 ++ 进程通信的代价大 ++ 进程之间的并发性粒度较粗,并发度不高 ++ 不适合并行计算和分布并行计算的要求 ++ 不适合客户/服务器计算的要求 + +解决问题的基本思路:把进程的两项功能——“独立分配资源”和“被调度分派执行分离开来”。前者仍交由进程处理,后者则交给称为线程的实体完成。 + +### 3.4.2 线程的基本概念 + +#### 1.进程与线程的比较 + +线程具有许多传统进程所具有的特征,所以又称为轻型进程或进程元。 + +在引入了线程的操作系统中,通常一个进程都拥有若干个线程,至少也有一个线程。 + +| | 进程 | 线程 | +| -------- | :----------------------------------------------------------- | ------------------------------------------------------------ | +| 调度性 | 传统操作系统中作为独立分派、调度的基本单位。 | 引入线程的操作系统中独立分派、调度的基本单位,而进程则作为资源拥有的基本单位。 | +| 并发性 | 进程之间可以并发执行,但若没有引入线程,当进程阻塞时,整个进程都无法完成其他任务。 | 线程之间同样可以并发执行,进程的一个线程阻塞,其他线程仍可提供服务。 | +| 拥有资源 | 是系统中拥有资源的一个基本单位。 | 虽然拥有一点关键资源,但不算拥有资源的单位。共享进程的资源。 | +| 系统开销 | 创建或撤销进程时系统需要为之创建和回收PCB,分配或回收资源。 | 远小于进程的开销,线程的切换也仅需保存和设置少量寄存器内容。同一个线程中的进程共享地址空间,因此同步和通信也较为容易。 | + +线程的状态和状态转换类似于进程,但一部分状态时没有意义的,例如线程没有挂起状态。 + +#### 2.线程的属性 + ++ 轻型实体 ++ 独立分派调度的基本单位 ++ 可并发执行 ++ 共享进程资源 + +线程可以独立调度,但不算是拥有资源的单位。 + +**线程共享的资源*:** + ++ 地址空间 ++ 全局变量 ++ 打开文件 ++ 子进程 ++ 信号 + +**独享的资源*:** + ++ 程序计数器 ++ 寄存器 ++ 栈 ++ 状态字 + +### 3.4.3 线程管理和线程库* + +#### 1.线程状态 + +每个线程: + ++ 线程标识符 ++ 一组状态参数 + + 寄存器状态 + + 堆栈 + + 线程运行状态 + + 优先级 + + 线程专存存储器 + +线程的运行状态:执行、就绪、阻塞。 + +#### 2.线程的创建和终止 + +初始化进程:应用程序启动时有的进程 + +终止:自我终止或他人强制终止 + +由线程库(用户空间运行/内核中运行)提供的基本线程控制原语: + ++ 孵化(spawn) ++ 封锁(block) ++ 活化(unblock) ++ 结束(finish) + +#### 3.多线程操作系统中的进程 + ++ 独立拥有资源 ++ 可分为多个线程 ++ 不是可运行的实体 + +### 3.4.4 线程的实现 + +#### 1.内核级线程 + ++ 完全在内核空间实现 ++ 内核空间设置线程控制块 ++ 由OS进行线程调度,资源分配等 ++ 由OS维护线程的信息 + +优点: + ++ 多处理器系统中,内核能同时调度同一进程中多个线程并行执行 ++ 阻塞线程不会阻塞进程 ++ 内核态线程具有很小的数据结构和堆栈,线程切换快,开销小 ++ 内核本身可采用多线程技术,提高系统执行速度和效率 + +缺点: + ++ 效率低 ++ 内核实现需要占用内存资源 ++ 需修改操作系统 + +#### 2.用户级线程 + ++ 在用户空间实现 ++ 用户空间建立线程库:一组管理线程的进程 ++ 用户自己写执行,系统进行调度 ++ 线程资源合作 ++ 操作系统不知道线程的存在 + +优点: + ++ 线程切换快:不需要陷入内核空间 ++ 应用程序特定需要选择调度算法:可选择最好的算法 ++ 灵活性:可在任意操作系统实现 + +缺点: + ++ 编程困难 ++ 多线程应用不能利用多处理机提高并行效率 ++ 系统调用的阻塞问题,线程受阻导致整个进程受阻 + +如何解决用户级线程的阻塞问题: + ++ 修改操作系统 ++ 激活受阻进程的其他线程 + + 激活进程调度器 + + 方法:第二次机会法 ++ 问题 + + 仍需小幅更改操作系统 + + 违反了操作系统设计的层次结构 + +#### 3.组合式线程 + +将内核态和用户态实现结合起来 + ++ 操作系统管理内核级线程 ++ 线程库管理用户态线程 ++ 一些用户态线程映射成内核态 + +#### 4.比较 + +用户级线程的切换速度更快,但用户级线程系统调用不如内核级线程,同时内核级线程的时间分配更合理。 + +## 3.5 进程通信(Inter Process Communication) + +> 进程通信,是指进程之间的信息交换,其所交换的信息量少者是一个状态或者数值,多者则是成千上万字节。 + +进程间的互斥和同步交换的信息量较少,因此被称为低级通信。 + +信号量机制尽管适合作为同步工具,但作为通信工具有如下缺点: + ++ 效率低 ++ 通信对用户不透明 + +而高级进程通信,是指用户可直接利用操作系统所提供的一组通信命令高效地传送大量数据的一种通信方式。系统实现,隐藏实现细节(即通信过程对用户是透明的)。 + +### 3.5.1 进程的通信方式 + +#### 1.共享存储器系统(shared-memory system) + +相互通信的进程共享某些数据结构或共享存储区,进程之间能够通过这些空间进行通信。 + ++ 共享数据结构,需要设置公用数据结构,处理进程同步。是低效的,只适用于传递相对少量数据。 ++ 共享存储区,在存储器中划分出一块共享存储区,进程通过对共享存储区中的读/写实现通信。 + +#### 2.消息传递系统 + +消息传递系统(message passing system)是当前应用最广泛的一种进程间的通信机制。该机制中,进程间的数据交换以格式化的消息(message)为单位,计算机网络中又把消息称为报文。程序员直接利用系统提供的通信命令(原语)即可传递大量数据。 + ++ 直接通信方式 + + `send(P,message)`,把一个消息发送给进程P + + `receive(Q,message)`,从进程Q接收一个消息 + ++ 间接通信方式(信箱) + + 进程间发送或接收消息通过一个共享的数据结构——信箱进行。每个信箱有一个唯一的标识符。 + + `send(A,mail)`,把一封信件(消息)传送到信箱A + + `receive(A,mail)`,接受信件,若无信件,则将进程置为等待状态 + +信箱是存放信件的存储区域,信箱可分为信箱头和信箱体。头储存容量、格式、位置指针等。体存放信件。 + +#### 3.管道通信系统 + +管道是指用于连接一个读进程和一个写进程以实现它们之间通信的一个共享文件,又名pipe文件。 + +管道机制必须提供以下三个方面的协调能力 + ++ 互斥,一个进程读/写时另一进程等待 ++ 同步,一个进程写入一定数据量后,应睡眠等待,读进程取走后再唤醒写入,反之亦然。 ++ 确定对方是否存在,确定对方存在时才能进行通信。 + +## 3.6 进程同步(原3.4) + +进程同步的引入: + +由于程序的异步性,可能会导致程序执行结果的不一致。 + +控制进程的执行以及执行顺序称为**进程同步**。 + +**主要任务**:对多个相关进程在执行次序上进行协调,使并发执行的诸进程之间能有效地共享资源和相互合作,从而使程序的执行具有可再现性。 + +### 3.6.1 进程同步的概念 + +多道程序环境下,并发执行的程序可能存在如下两种形式的制约关系: + ++ 资源共享关系(竞争关系,间接制约关系) + + 进程共享一套的计算机系统资源,会出现竞争资源的关系。 + + 进程的互斥(mutual exclusion)是解决进程间竞争关系的手段,也成为间接同步。 + ++ 相互合作关系(协作关系,直接制约关系) + + 进程为完成一个任务需要分工合作,因为进程的异步性,进程独立地以不可预知地速度推进,这就需要相互协作的进程在某些协调点上协调各自的工作。 + + 进程的同步(synchronization)是解决进程间协作关系的手段,也称直接同步。 + +进程同步指对进程与进程之间的穿插进行控制。而互斥也是通过逐次使用互斥资源,协调了资源的使用顺序,也是间接地对进程顺序的协调。 + +### 3.6.2 临界区及其管理 + +#### 1.临界资源和临界区 + +>**临界资源**:一次仅允许一个进程访问的资源 +> +>**临界区**:进程访问临界资源的代码段 + +#### 2.临界区管理 + +同步机制应当遵循的4个准则: + ++ 空闲让进 ++ 忙则等待:有一进程进入临界区时,其他进程等待 ++ 有限等待 ++ 让权等待:等待时应当放弃CPU + +#### 3.高级进程同步机制 + +#### 1.锁(Mutex) + ++ 锁阻止了其他进程进入临界区 + ++ 两个基本操作: + + ```c + Lock lock(Lock lock)//等待锁达到打开状态,获得锁并锁上 + { + while(1) + { + if(lock.isfree()) + { + return lock; + } + } + } + void unlock(Lock lock){lock.free()}; + ``` + ++ 四个基本要素 + + + 锁的初始状态要是打开状态 + + 进入临界区前必须获得锁 + + 出临界区时必须打开锁 + + 如果别人持有锁则必须等待 + +#### 2.睡眠与唤醒 + ++ `sleep()`原语 ++ `wake up()`原语 + +wake up由其他进程执行。 + +### 3.6.3 信号量及PV操作 + +1965年,E.W.Dijkstra提出了一种卓有成效的进程同步工具:信号量(semaphore)机制。 + +在信号量机制中,有**检测**(Probern,P,检测,荷兰语)和**归还**(Verhogen,V,增量,荷兰语)两个重要的操作。 + ++ P操作(wait,down):表示同步进程发出的检测信号量操作,检测是否能够使用临界资源,如果不能使用则等待正在使用的进程归还临界资源 ++ V操作(signal,up):将临界资源释放 + +PV操作都是原子操作。 + +信号量的类型: + ++ 整型信号量 ++ 记录型信号量 ++ AND型信号量 ++ 信号量集 + +#### 1.整形信号量 + +设S为一个需要初始化的整形变量,对S的访问仅能通过两个标准的原子操作P(S)和V(S)。 + +S的初值可为0或1 + +```c +void P(int S) +{ + while(S<=0){} + S=S-1; +} +void V(int S) +{ + S=S+1; +} +``` + +如果S的值为1,表示有一个临界资源可供使用,P(S)检测通过后,S值被减为0。 + +如果S值为0,表示没有临界资源,P(S)检测不能通过,进程等待。 + +由于在等待过程没有放弃CPU控制权,违背了"让权等待"的原则。 + +记录型信号量解决了这一问题。 + +#### 2.记录型信号量 + +让不能进入临界区的进程“让权等待”,进入阻塞队列等待。 + +设S为一个记录型数据结构,S的定义如下: + +```c +#define A 1000 +typedef struct semaphore +{ + int value; + PCB L[A];//阻塞队列 +}Semaphore; +``` + +相应的,PV操作可描述为: + +```c +void P(Semaphore S) +{ + S.value-=1; + if(S.value<0) block(S.L);//将调用P的进程阻塞,并放入阻塞队列 +} +void V(Semaphore S) +{ + S.value+=1; + if(S.value<=0) wakeup(S.L);//从阻塞队列唤醒一个在等待的进程 +} +``` + +#### 3.AND型信号量 + +上述的进程互斥问题都仅仅针对共享一个临界资源而言。而当进程需要获得两个或更多的临界资源才能完成任务时,有可能由于进程语句顺序不当而造成**死锁**状态, + +AND型信号量便是为了解决此类问题。 + +解决思路:将进程所需要的资源一次性分配。 + +AND型信号量可定义为: + +```c +void P(S1,S2,...,Sn) +{ + if(S1>1 && S2>1 && ... && Sn>1) + { + for(int i=0;it1 && ... && Sn>tn) + { + for(int i=0;i<=n;i++) + { + Si-=di; + } + } + else + { + 将当前进程插入Si的等待队列,Si是第一个不满足Si>ti的信号量,程序计数器设为P操作的开始; + } +} +void V(S1,d1,...,Sn,dn) +{ + for(int i=0;i<=n;i++) + { + Si+=di; + 唤醒Si等待队列的所有进程; + } +} +``` + +三种特例: + +`P(S,d,d)`:只有一个信号量S,但允许每次申请d个资源,资源小于d时不分配 + +`P(S,1,1)`:此时信号量集以及蜕变为一般的记录型信号量 + +`P(S,1,0)`:特殊且有用的信号量操作,当S>=1时允许多个进程进入特定区,但当S为0后阻止任何进程进入,相当于一个可控开关。 + +#### 5.信号量的应用 + ++ 实现进程互斥 ++ 描述前趋关系 + +常见问题:生产者-消费者、哲学家进餐问题、读者-写者问题。 + +考试时要会利用信号量解决实际问题。 + +```c +Semaphore hall=200; +Semaphore conductor=1; + +void buy() +{ + P(hall); + P(conductor); + buyticket(); + V(conductor); + v(hall); +} +``` + +**使用信号量时注意**: + ++ PV(wait和signal)必须成对出现。 ++ 用于实现互斥的PV必须成对出现在一个程序中,但对资源信号量的PV可能成对出现在不同的程序中。 ++ 要注意P操作的顺序,防止进程死锁。 + +### 3.6.4 管程* + +引入管程的原因:为了避免凡是要使用临界资源的进程都自备同步操作P和V,将同步操作的机制和临界资源结合到一起,形成一种新的同步工具,管程(monitors)。 + +目的是避免PV过多以及使用不当引起死锁。 + +#### 1.管程的定义 + +> 一个数据结构和能够为并发进程所执行的在该数据结构上的一组操作。 + +#### 2.管程的特性 + ++ 模块化 ++ 抽象数据类型 ++ 信息封装 ++ 任意时刻,在管程中只能由一个进程 + +## 3.7 死锁(原3.6) + +### 3.7.1 死锁的定义 + +多道程序中,多个程序并发执行可能引发一种危险——**死锁**。 + +> 死锁,是多个进程在运行过程中**争夺资源**而造成的一种僵局,当进程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进。 + +> **资源**:进程运行需要的事物。 + +### 3.7.2 产生死锁的原因 + +进程需要以一种合理的顺序来访问资源 + +产生死锁的原因: + ++ 竞争资源引起死锁 ++ 进程间推进次序不当 + +产生死锁必须满足4个条件: + ++ 互斥条件:某资源在一个时间内只能由一个进程占用 ++ 持有等待:线程在请求新的资源时,已经获得的资源不释放而是继续持有 ++ 不能抢占:不能强迫进程放弃资源 ++ 环路等待 + +### 3.7.3 处理死锁的方法 + +处理死锁的方法可归结为: + ++ 不予理睬:忽略问题的存在 + + 此种策略在如下情况下合理: + + 死锁出现的概率很低 + + 预防死锁的代价很大 + + UNIX和windows都采用此方法 + + 是方便和正确性的一种折中 ++ 静态预防:消除死锁的4个必要条件的任意一个 + + 消除资源独占条件(互斥条件) + + 一些设备可以被共享 + + 但不是所有设备都可以被共享 + + 消除持有等待条件 + + 进程启动时请求所有资源 + + 缺点:资源浪费、可能无法得知所需的所有资源 + + 消除非抢占条件 + + 允许抢占CPU(信息保存到进程控制表)/内存(内存导出到硬盘) + + 局限性:有些资源不可被抢占:如锁、打印机 + + 消除环路等待条件 + + 指定需要资源的顺序 + + 或增加资源,最小化死锁的概率 ++ 动态避免:仔细地资源分配 ++ 死锁检测、解除死锁:成对地解决方法,在死锁发生后采取措施纠正 + +### 3.7.4 死锁检测和修复* + +注意资源的占有和资源需求。 + +资源分配图以及检测: + ++ 有向图检测 ++ 矩阵检测 + +死锁的恢复: + ++ 剥夺资源 ++ 杀死进程 + +### 3.7.5 死锁的动态避免(银行家算法) + +Dijkstra在1965年提出了银行家算法,源于银行家发放贷款时采取的控制方法。 + ++ 事先声明所需的最大资源(但实际并不获得最大资源) ++ 在之后进程请求资源时 + + 若分配资源后仍处于**安全状态**,满足要求 + + 否则阻塞进程 + +银行家算法的数据结构: + ++ 可利用资源向量Available + + 例:`Available={3,3,2}` + + | A | B | C | + | :--: | :--: | :--: | + | 3 | 3 | 2 | + + 其中的每个元素代表一类可利用的资源数目 + + `Available[j]=k`代表系统现有`Rj`类资源`k`个 + ++ 最大需求矩阵Max + + 例:`Max={ {7,5,3},{3,2,2},{9,0,2},{2,2,2},{4,3,3} }` + + | 进程\资源 | A | B | C | + | :-------: | :--: | :--: | :--: | + | P0 | 7 | 5 | 3 | + | P1 | 3 | 2 | 2 | + | P2 | 9 | 0 | 2 | + | P3 | 2 | 2 | 2 | + | P4 | 4 | 3 | 3 | + + 是一个n*m矩阵,表示系统中n个进程的每一个进程对m类资源的最大需求。 + ++ 分配矩阵Allocation + + 也是一个n*m矩阵,表示当前每一类资源已经分配给进程的资源数 + ++ 需求矩阵Need + + 同样是一个n*m矩阵,用以表示每一个进程尚需的各类资源数 + + `Need[i][j]=Max[i][j]-Allocation[i][j]` + +银行家算法流程: + ++ 对于请求向量Request进行检测,若请求的资源大于需求资源Need,则拒绝 ++ 若请求的资源大于可用资源Available,拒绝,没有足够资源分配,需要等待 ++ 试探性分配资源并进行**安全性检测**,若分配后状态安全,则进行分配,否则拒绝 + +安全性算法(简要自然语言描述): + +若能找到一个序列,系统的剩余资源能按次序完成(一个进程完成后,拥有的全部资源会归还)每个进程的请求,则当前状态安全。 + +**考试要求**:要会使用银行家算法对Request进行分析。 + +--- + +# 第四章 处理机调度 + +处理机是计算机系统中的重要资源,在多道程序环境下,进程数目>处理机。系统需要按照一定方法动态地分配给就绪队列。处理机利用率和系统性能很大程序取决于处理机调度。 + +**处理机调度是操作系统设计的中心问题之一。** + ++ WHAT:按什么分配 ++ WHEN:何时分配CPU ++ HOW:如何分配CPU + +> **处理机调度**:指在多道程序环境中将处理机分配给进程。 + +## 4.1 处理机调度的层次 + +> **作业**是用户在一次解题或一个事务处理过程中要求计算机系统所作工作的集合,包括用户程序、所需的数据及命令等。 + +作业的状态:后备、运行、完成。 + +![作业的状态转换](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/os_03.png) + +### 4.1.1 高级调度 + +> 高级调度也称为**作业调度**、**长程调度**或接纳调度。 +> +> 主要任务是为作业分配内存、资源,放入就绪队列。 + +每次作业调度时,需决定: + ++ 接纳多少个作业 + + 取决于多道程序度,即允许多少个作业同时在内存中运行 + + + 作业太多:服务质量下降 + + 作业太少:资源利用率低 + ++ 接纳哪些作业 + + 取决于作业调度算法: + + + 先来先服务 + + 短作业优先 + + 作业优先权调度 + + 响应比调度 + +### 4.1.2 低级调度 + +> 低级调度也称为**进程调度**或**短程调度** +> +> 主要任务是按某种策略和方法选取一个就绪进程,分配处理机 + +低级调度分为**抢占式**和**非抢占式**两种。 + ++ 非抢占式:当前进程不会被优先级更高的进程抢占 + + 引起进程调度的因素 + + + 正在执行的进程执行完毕,或因发生某事件不能继续执行。 + + 执行中的进程因I/O暂停 + + 进程执行了某种原语操作,如`wait`/`block` + + **优点**:算法简单,系统开销小 + + **缺点**:紧急任务不能及时响应;短进程等待长进程 + ++ 抢占式 + + 若有某个更为重要或紧迫的进程进入就绪队列,则暂停当前进程,将处理机分配给这个更为重要或紧迫的进程。 + + 抢占式调度主要有以下原则 + + + 优先权原则 + + 短进程优先原则 + + 时间片原则(分配的时间片用完后停止执行) + + **优点**:适用于时间要求严格的实时系统 + + **缺点**:调度算法复杂,系统开销大 + +低级调度的时间尺度往往是毫秒级的,由于频繁使用因此要求在实现时做到高效。 + +### 4.1.3 中级调度 + +> 中级调度也称为中程调度 + +引入目的:提高内存利用率和系统吞吐量 + +主要任务:按照给定的原则和策略,交换内存和外存 + +### 4.1.4 处理机调度的目标(原4.3.1) + ++ 对于I/O密集型程序,极小化平均响应时间 + + 平均化做每项工作的时间 ++ 对于计算密集型程序,极大化系统吞吐量 + + 单位时间内完成尽可能多的程序 ++ 对于平衡性程序,响应时间和周转时间达到平衡 + +### 4.1.5 不同系统的调度目标(原4.3.1) + ++ 批处理系统 + + 系统吞吐率:最大化单位时间的工作量 + + 周转时间:最小化任务提交到结束之前的时间 + + CPU利用率:保证CPU始终在繁忙工作状态 ++ 交互式系统 + + 快速响应需求 + + 满足用户期望 ++ 实时系统 + + 截止时间内满足需求 + + 避免丢失数据 + + 提供性能可预测性 + +## 4.2 调度队列模型及调度准则* + +### 4.2.1 调度队列模型 + ++ 仅有进程调度的调度队列模型 ++ 具有高级和低级调度的调度队列形式(批处理系统) ++ 同时具有三级调度的调度队列模型 + +### 4.2.2 选择调度方式和算法的若干准则 + +#### 1.面向用户的准则 + ++ 周转时间短(周转时间:完成时间-到达时间,带权:周转时间/服务时间) ++ 响应时间快(交互性作业) ++ 截止时间的保证(特别是对于实时系统) ++ 优先权准测 + +#### 2.面向系统的准则 + ++ 吞吐量高(特别是对于批处理系统) ++ 处理机利用率好 ++ 各类资源的平衡利用 + +## 4.3 调度算法 + +### 4.3.1 先来先服务 + +> **先来先服务**(First come, First serve, FCFS)是最简单的非抢占式调度算法,它是指按照作业或进程进入系统的先后次序进行调度。 + +先进入系统者先调度,即启动等待时间最长的进程。既可用于作业调度,也可用于进程调度。 + +**优缺点:** + ++ 有利于长作业(进程),而不利于短作业(进程) ++ 有利于CPU繁忙型进程(作业),而不利于I/O繁忙型进程(作业) ++ 用于批处理系统,不适用于分时系统 + +### 4.3.2 短作业(进程)优先调度算法 + +> **短作业(进程)优先调度算法**(short job first,SJF/short process first,SPF)是指以运行时间长短进行调度,启动运行时间最短的作业(进程)。 + +**优缺点:** + ++ 能够降低平均周转时间和平均带权周转时间 ++ 对长作业不利,长作业长期不被调度引发饥饿 ++ 没有考虑作业的紧迫程度 ++ 运行时间仅能估算,实际会有变动 + +### 4.3.3 高优先权调度算法 + +> 为了照顾紧迫作业,使之在进入系统后便获得优先处理,引入了**最高优先权优先**(first priority first, FPF)算法。 + +分为抢占式(会立即结束当前进程)和非抢占式。 + +都会把处理机分配给最高优先权的进程,当有更高优先权的进程到达时,抢占式算法将立即停止当前进程的执行,处理机分配给优先权最高的进程,非抢占式算法将不会比较优先级,首先将当前进程执行完毕。 + +确定进程优先权的依据有以下三个方面: + ++ 进程类型 ++ 进程对资源需求 ++ 用户要求 + +优先权的类型: + ++ 静态优先权:在创建进程时确定 + + 系统开销小 + + 不够精确 ++ 动态优先权 + + 随着进程的推进/等待时间的增加而改变 + + 可规定就绪队列中的进程随等待时间增长,优先权提高 + + 在抢占式FPF中,也可规定执行中的进程随执行时间增长,优先权降低 + +### 4.3.4 高响应比优先调度算法 + +是FCFS和SJF的结合 + +> **高响应比优先调度算法**(Highest Response Ratio First, HRF)的调度策略是使响应比最高的作业优先启动。 + +优先权=响应时间(等待时间+服务时间)/服务时间 + +等待时间相同的作业,要求服务时间越短,优先权更高 + +服务时间想通过的作业,等待时间越航,优先权越高 + +优先权随等待时间增加而提高 + +是一种折衷,既照顾了短作业,又考虑了到达的先后次序 + +**缺点**:要进行响应比计算,增加了系统开销 + +### 4.3.5 简单的时间片轮转算法 + +> **时间片轮转**(Round Robin, RR)是指系统将所有的就绪进程按先来先服务的原则排成一个队列,每次调度时给队首分配一个时间片。时间片用完时加入队尾。 + +**缺点**:紧迫任务响应时间慢 + +### 4.3.6 多级反馈队列调度算法 + +是目前公认的一种较好的进程调度算法。 + +> 设置多个就绪队列,并为各个队列赋予不同的优先级 +> +> + 第一个队列优先级最高,之后依次降低 +> + 第一个队列分配的时间片最短,之后依次加长 +> + 第一个队列分配的时间片用完后,置入第二个队列,以此类推 + +![调度过程](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/os_04.png) + +多级反馈队列调度算法具有较好的性能,能很好地满足各种类型用户的需要。 + +## 4.4 实时调度 + +先前的调度算法关注平均化的分析,而对于实时系统,必须保证在截止时间前完成任务(例:视频输入,物理控制系统) + +### 4.4.1 实时调度的基本条件 + ++ 提供必要的调度信息 + + 就绪时间 + + 开始/完成截止时间 + + 处理时间 + + 资源要求 + + 优先级 ++ 系统处理能力强 ++ 具有快速切换机制 + +### 4.4.2 常用的几种实时调度算法 + +#### 1.最早截止时间优先(EDF) + +总是运行最早结束的作业 + +#### 2.最低松弛度优先(LLF) + +松弛度:A需在200ms前完成,运行需100ms,当前10ms,则A的松弛度为200-100-10=90ms + +## 4.5 进程调度的时机 + ++ 当一个进程运行完毕,或由于某种错误而终止运行 ++ 当一个进程在运行中处于等待状态(阻塞) ++ 分时系统中时间片到 ++ 有一个优先级更高的进程就绪 ++ 进程执行了某种原语 + +--- + +# 第五章 存储管理 + +## 5.1 存储器 + +### 5.1.1 存储器的层次结构 + +实际情况的内存架构: + ++ CPU寄存器:低容量、高速度、高价格 + + 高速缓存 ++ 主存(内存):中容量、中速度、中价格 + + 内存的大小是衡量计算机性能的一个非常重要的指标 ++ 辅存(外存):大容量、低速度、低成本 + +不同层次的存储介质,均有操作系统进行统一管理,存储管理主要负责内存、高速缓存的管理,外存的管理则交由设备和文件管理负责。 + +> 计算机中的内存也称为物理内存,其地址从最低开始到最高上界,按照顺序编号。内存中的地址称为**物理地址**。 + +而在操作系统中,存储管理功能负责为进程分配和回收内存,实现内存空间在时间和空间上的复用。 + +### 5.1.2 程序的装入和链接* + ++ 用户用高级语言编写的源程序,需要经过编译、链接和装入后,才能被处理器运行。 + +> 程序装入内存前,装入模块中给出的程序地址为程序的**逻辑地址**,一个用户的所有装入模块的逻辑地址集合称为该作业的**逻辑地址空间**。 +> +> 用户作业被装入内存后,进程物理地址的总体构成了**物理地址空间**。 +> +> 为保证用户作业的正确运行,必须把用户作业的逻辑地址转化为物理地址,这一过程称为**地址变换**或**重定位**。 + ++ **编译**是将用户用高级语言编写的源程序转化为目标模块 ++ **链接**将用户需要的所有目标模块链接在一起,形成一个可执行模块,即装入模块 + + 静态链接:链接过程在程序装入内存前完成,形成整个程序的逻辑地址空间 + + 装入时动态链接 + + 便于模块修改和更新 + + 便于目标模块的共享 + + 运行时动态链接 + + 不运行的模块,不需要链接 ++ **装入**将装入模块放入内存 + + 绝对装入方式:对程序员要求很高,适合用于实时操作系统和嵌入式操作系统 + + 静态重定位装入方式 + + 动态重定位装入方式:可以在程序运行时重新定位程序在内存中的地址,以便于虚拟存储器等功能 + +### 5.1.3 存储器管理的两个目标 + ++ 地址独立:程序发出的地址与物理主存地址无关 ++ 地址保护:一个进程不能访问另一个进程的地址空间 + +## 5.2 连续存储空间管理 + +> 连续存储空间,是指为一个用户程序分配一个连续的内存空间 + +可进一步划分为: + ++ 单一连续分配 + + 最早出现,应用于单道编程 ++ 固定分区分配 + + 应用于多道编程 ++ 动态分区分配 + + 应用于多道编程 ++ 动态分区重定位 + +### 5.2.1 单一连续分配 + ++ 是最简单的存储管理方式,只用于单用户、单任务的系统中。 + ++ 内存分为系统区和用户区 + + 系统区仅提供给操作系统使用 + + 用户区提供给用户使用 ++ 达到了地址独立 ++ 达到了地址保护(整个系统只有一个用户程序) ++ 问题 + + 将整个程序加载到内存空间 + + 浪费资源 + +### 5.2.2 固定分区分配 + ++ 多道编程中最简单的内存管理方式 + + 将内存划分为几个固定的区域,可同时装入多个作业/任务 + + 程序被加载到固定的分区 ++ 分区大小 + + 大小相等:缺乏灵活性 + + 大小不等:多个较小分区,适量中等分区以及少量大分区 ++ 分配到分区的选择 + + 每个分区一个进程队列,每个队列进入固定分区 + + 单一输入队列,新进程可以进入任意分区 ++ 固定分区分配的地址变换也有静态重定位方式和动态重定位方式 ++ 地址变换借助于下限寄存器和上限寄存器 + + 进程的逻辑地址+下限寄存器中的基址为物理地址 + + 若物理地址落入上下限寄存器地址中则有效,否则访问越界,拒绝分配分区 ++ 缺点: + + 内存利用率不高(内存碎片) + + 划分分区大小困难 + + 需要预先知道进程大小 + +### 5.2.3 动态分区分配 + ++ 根据作业的实际需要,动态地为其分配内存空间 + + + 为了完成分配和回收分区,需要构建对分区信息描述地数据结构,并完成分区分配算法与回收方法 + ++ 数据结构 + + + 空闲分区表:包括分区号、分区始址,分区大小 + + 空闲分区链:空闲分区最常用地组织形式,所有地空闲分区通过前向和后向指针串在一起组成双向空闲分区链 + ++ 分区分配算法 + + + 首次适应法 + + + 空闲分区链按照地址递增的顺序组织 + + 每次分配内存时,遍历分区链,找到满足大小分区时分割一部分给程序 + + 找不到则分配失败 + + **缺点**:大空闲分区被分割、每次查找都从链首开始,增加了查找的开销 + + + 循环首次适应法 + + + 空闲分区链按照地址递增的顺序组织 + + 每次分配内存时,从空闲分区链上上次为作业分配分区后的位置开始查找 + + 克服了空闲空间分布不均的问题,但碎片空间问题仍没有得到解决 + + + 最佳适应算法 + + + 空闲分区链按照分区大小递增的顺序组织 + + 从分区链中挑选一个满足进程要求的最小分区进行分配 + + 是一种较优的分区分配算法,但剩余的空闲分区很小,这一部分很小的碎片,难以再次利用 + + + 最坏适应算法 + + + 空闲分区链按照分区大小递减的顺序进行组织 + + 从分区链中挑选一个满足作业要求的最大分区 + + 系统会缺乏较大的空闲分区 + + + 快速适应算法 + + + 空闲分区根据容量大小进行分类,单独设立空闲分区链 + + 内存中设一张管理索引表,每一个表对应了空闲分区类型 + + 分配时根据大小从对应索引表找到对应空闲分区链的起始指针,开始查找分配 + + 该算法查找效率高,对大的作业不会产生内存碎片 + + 缺点是回收分区困难,算法复杂,系统开销大 + ++ 分区分配和回收操作 + + + 分区分配:首先根据分配算法中查找所需大小的分区。分区分配成功后会将分配区的首地址返回给分配过程的调用者。 + + + 分区回收:作业完成时会释放内存,系统需要回收,**回收的内存进入空闲分区链才能再次分配**。 + + 根据分区的首地址,有四种不同的情况: + + + 上邻空闲区:合并,修改大小 + + 下邻空闲区:合并,修改大小、首地址 + + 上下邻空闲区:合并,修改大小 + + 不邻接:建立一新表项插入空闲链的适当位置 + ++ 存在的问题 + + + 难以增长进程空间(如栈,数据等) + + 解决方案:为增长的栈和数据段分配空间 + +### 5.2.4 可重定位分区分配 + +动态重定位的引入:连续分配方式中,总量大于作业大小的多个小分区不能容纳作业。 + +通过作业移动将小分区拼接成大分区,作业的移动需要重定位。 + +### 5.2.5 对换 + +> 对换:把内存中暂时不能运行的进程或者暂时不用的程序和数据调出到外存上,以便腾出足够的内存空间 +> +> 整体对换:进程对换 +> +> 部分对换:分页对换 + +为实现进程对换,系统须实现三方面功能: + ++ 对换空间的管理 ++ 进程的换出 ++ 进程的换入 + +外存 + ++ 文件区:注重空间利用率,一般采用离散存储方式 ++ 对换区:注重速度,采用连续分配方式 + +换出 + ++ 选择被换出进程:考虑进程状态、优先级、驻留时间 ++ 换出过程:若为共享段,必须计数-1后为0(没有进程需要)才换出,否则不换出。修改PCB。 + +换入 + ++ 选择换入进程:考虑进程就绪、优先级、换出时间 ++ 申请内存 ++ 换入 + +连续分配方式的问题: + ++ 很难增长地址空间 ++ 不能运行大于物理内存的程序 ++ 外部碎片 + +如何解决以上问题?分页。 + +## 5.3 分页存储管理 + +### 5.3.1 分页存储管理的基本思想 + ++ 将物理内存分配成固定大小的块(或页框) + + 固定单元易于分配 + + 任何空闲物理页可以存储任何逻辑页 ++ 将逻辑空间分成相同大小的页 + + 每个逻辑页可以存在物理内存上或导出到磁盘上 ++ 进程通过逻辑地址访问内存 ++ 页面大小不能太大(导致碎片)也不能太小(页表过长,效率低),一般是512B~8K + +### 5.3.2 分页系统中的地址结构 + ++ 页面号 ++ 页内偏移量 + +通过页表实现逻辑页面和物理块之间的映射关系 + +处理器可以通过**页表的一个有效/无效位**知道逻辑页面是否在物理内存中 + +页面可以有不同的保护方式(可读、可写、可执行),这些信息也**保存在页表中** + +#### 1.页表 + ++ 页表是分页系统的关键组成组件 ++ 是一个硬件数据结构,实现逻辑页面和物理块之间的映射关系 ++ 页表内容: + + 是否存在物理内存中的标志位、 + + 物理页面号 + + 修改位:加载后是否被修改过 + + 访问位:页面被读/写 + + 保护位 + +#### 2.页面翻译过程 + +``` +块内偏移=页内偏移 +物理地址=块号*块长+块内偏移 +``` + +#### 3.地址变换机构 + +**基本任务**:实现从逻辑地址到物理地址的转换 + +借助页表完成,页表大多驻留内存 + +每个进程对应一个页表,未执行时其信息放入PCB中,执行时将页表的首地址装入页表寄存器。 + +系统只设置一个页表寄存器,存放页表在内存的首地址和页表长度 + +![地址变换机构](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/os_05.png) + +分页系统存在的问题:页表的尺寸可能很大 + +解决方案:使用二级/多级页表 + +### 5.3.3 两级和多级页表 + +一级页表存放二级页面的信息,...... + +最后一级存放对应的物理地址 + +地址的转化: + +一级->二级->地址+偏移 + +使用多级页表会增加内存的访问次数 + +### 5.3.4 快表 + +> 翻译快表,缩写为TLB(Translation Look-Aside Buffer),用于加快地址翻译的过程。 + ++ 加快了内存访问速度 ++ 缓存了从虚拟页面到物理页面的映射 + +具有快表的地址变换过程:先查询快表,若该页不在快表中,则再查询页表,并把该页的映射写入快表,快表若已满,则换出很久未查询的映射。 + +![快表的地址变换](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/os_06.png) + +分页系统的缺陷: + ++ 共享困难:页面中只要有一行地址不能共享,整个页面就不能共享 ++ 每个进程占用一个虚拟地址空间,可能发生碰撞 + +解决方案:分段。 + +## 5.4 分段存储管理 + +### 5.4.1 分段存储管理的引入 + +为了满足下列一系列需要 + ++ 方便编程 ++ 分段共享 ++ 分段保护 ++ 动态链接 ++ 动态增长 + +### 5.4.2 分段系统的基本原理 + ++ 分段系统把一个程序按照逻辑单元分成多个程序段 + ++ 每一段使用自己单独的虚地址空间 + ++ 依旧是离散的存储方式 + ++ 注意:并不是所有虚拟地址都有效 + + + 有效意味着该区域是进程虚拟地址空间的一部分 + + 无效意味着虚拟地址是非法的 + + 物理地址=基址+段内偏移 + ++ 保护:不同的段可以有不同的保护 + ++ 使用段表储存分段信息 + +| 分页 | 分段 | +| :--------------------------: | :--------------------------: | +| 提高内存利用率 | 满足用户需要 | +| 一个线性地址空间 | 多个线性地址空间 | +| 整个地址空间可以超过内存尺寸 | 整个地址空间可以超过内存尺寸 | +| 程序和数据不可单独保护 | 可以实现单独保护程序数据 | +| 尺寸不易变化 | 尺寸容易变化 | +| 不可以共享程序 | 可以共享程序 | + +如何结合两者优点:段页式内存管理 + ++ 将程序分为多个逻辑段 ++ 每个段里又进行分页 + +![段页式存储管理](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/os_07.png) + +段页式地址管理的地址变换机构: + +![引入挂起的状态转换](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/os_08.png) + +## 5.5 虚拟存储器管理 + +### 5.5.1 虚拟存储器的概念 + +计算机系统的内存容量是有限的,而传统存储器管理中,如果一个作业要运行,作业的全部信息必须装入内存。这限制了运行作业的大小以及数量。通过研究发现,进程执行时并非同时需要作业的全部信息,可以将这些暂时不使用的信息调出内存。 + +> 将外存作为内存的补充,从逻辑上扩充内存,是虚拟存储管理的基本思想 + +程序和数据的访问具有如下特点: + ++ 顺序性 ++ 局限性 ++ 多次性 ++ 独立性 + +> **虚拟存储器**的定义:是指具有请求调入功能和置换功能,能够从逻辑上对内存空间进行扩展,允许用户的逻辑地址空间大于物理内存地址空间的存储管理系统。 + ++ 虚拟存储器中,一般将硬盘作为外存,因此,硬盘也被称为对换设备 ++ 虚拟存储器的基础是内存的离散管理,实现的方式为**请求分页式虚拟存储器管理**或**请求分段式虚拟存储器管理** ++ 请求分页式虚拟存储器管理 + + 以页为单位置换 + + 需硬件支持 + + 请求分页的页表机构 + + 缺页中断机构 + + 地址变化机构 + + 需实现请求分页的软件 + + 用于实现请求调页的软件 + + 实现页面置换的软件 ++ 请求分段式虚拟存储器管理 + + 以段为单位置换 + + 需硬件支持 + + 请求分段的段表机构 + + 缺段中断机构 + + 地址变化机构 + + 需实现请求分段的软件 + + 用于实现请求调段的软件 + + 实现段面置换的软件 ++ 虚拟存储器的特征 + + 多次型:最重要的特征 + + 对换性 + + 虚拟性 + +### 5.5.2 请求分页式虚拟存储器管理 + +基于内存的分页管理,需要增加**请求调页**和**页面置换**功能。 + +**请求调页**和**页面置换**也是虚拟存储管理的主要功能。 + +#### 1.请求分页的页表机制 + +除了页号和物理块号外,增加了页的状态位,外存地址,修改为,访问字段 + ++ 状态位:用于标志一个页面是否已经装入内存 ++ 外存地址:页面在外存中的地址 ++ 修改位:调入后是否修改过的标志 ++ 访问字段:在内存中是否被访问过 + +#### 2.缺页中断机构 + +发现访问的页面不在内存时,通知置换。 + +是特殊的一种中断,有如下不同: + ++ CPU检测中断时间不同 + + 一般中断信号:一个指令周期为间隔 + + 缺页中断信号:执行期间可检测,更及时 ++ CPU可多次处理 + + 一个指令周期多次检测到缺页中断,CPU都会及时处理 + + 处理过程需要软件和硬件同时完成 + +#### 3.地址变换机构 + +在程序运行过程中需要逐步将页面调入内存,在程序运行过程完成逻辑地址到物理地址的转换,是动态重定位装入。 + +![地址变换机构](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/os_09.png) + +虚拟存储器管理是以牺牲系统开销为代价,换取内存的逻辑补充。 + +在具体实施时,需要解决如下策略问题: + ++ 调页策略:何时将需要的页面调入内存 ++ 分配策略:应该分配多少内存中的物理块 ++ 内存置换策略:哪些页面被换出内存 + +#### 4.调页策略* + ++ 请求页调入:在CPU访问进程页面时,请求将页面调入内存 + + 优点: + + + 只有在需要时才将页面调入内存,节省了内存空间 + + 缺点: + + + 初次执行时,大量页面调入内存 + + 缺页时仅调入一个,I/O频率高 + + 执行顺序跳跃性大的程序,缺页情况变化大,难以趋向稳定的水平,系统不稳定 + ++ 预先页调入:预先动态估计进程可能要访问的页面,并在访问前预先调入内存 + + 优点: + + + 一次可调入多个页面,减少了中断、I/O次数 + + 缺点: + + + 依赖估计准确率 + + 需要程序预先提供部分信息,否则调度策略难以实施 + +#### 5.分配策略* + +物理块的分配策略: + ++ 进程平均分配法 ++ 进程按比例分配法 ++ 进程优先权分配法 + ++ 进程的最小物理块数:无论如何,首要是保证进程的正常运行 + +#### 6.内存置换策略 + +全局置换、局部置换 + ++ 可变分配全局置换:先分配一定量的物理块,需要时首先考虑空闲物理块,其次从全部中选择置换 ++ 固定分配局部置换:先分配一定数目,不改变,缺页时从当前进程的页面中置换 ++ 可变分配局部置换:先分配一定数目,缺页自身置换,**频繁缺页时,系统在分配若干物理块** + +### 5.5.3 页面置换算法 + +设计问题:需要一个空闲页面时选择哪个页面来进行置换。 + +目标:减少缺页中断的次数,即减少缺页率 + +影响缺页率的因素: + ++ 进程的内存物理块数 ++ 页面大小 ++ 程序的局部性 ++ 页面置换算法 + +#### 1.最佳置换算法 + ++ 选择一个随后最长时间不会被访问的页面进行置换 + + 产生缺页中断次数最小 + + 要具备预知未来的能力 + +是理论上的算法,难以实现:预知未来很困难 + +#### 2.FIFO(First in, First out)算法 + ++ 更换最早进入内存的页面 ++ 按照进入内存的次序维护一个所有页面的链表 ++ 每次替换链表头部的页面 + +缺点:可能出现最先加载进来的页面是经常被访问的页面 + +#### 3.最近最久未使用(LRU)算法 + ++ 使用过去的数据预测未来 ++ 如果一个页面长时间未被使用→可能之后很长一段时间也用不到 + +实现:矩阵/移位寄存器记录页面使用时间 + +#### 4.时钟算法 + ++ 每个页面常驻访问位,被访问时置1 ++ 访问位可以被操作系统清零 ++ 查找一个要被替换的页面时查看正在被指针指向的页面 + + 访问位为0则换出 + + 访问位为1则置0并指向下一位 + +#### 5.改进型时钟算法 + ++ 除考虑页面访问情况外,还需要考虑置换代价,即修改位 + +### 5.5.4 页面调度性能* + +虚拟存储器管理以时间换空间,是否值得要从缺页率、页面大小等方面分析。 + +缺页不仅会使缺页的进程运行减慢,也会影响其他进程的运行,因此分配物理块和选择置换算法需要慎重考虑。 + +对换空间的速度一般更快。 + +L=根号2nA为最佳页面长度 + +### 5.5.5 请求分段存储、请求段页存储管理 + +将段放入外存,在执行时调入内存 + +--- + +# 第六章 设备管理 + +## 6.1 I/O系统 + +### 6.1.1 I/O设备 + +I/O设备种类繁多,管理复杂,从OS角度看硬件,其性能指标有:设备使用特性、数据传输速率、数据的传输单位、设备共享属性等。 + ++ 按设备使用特性分类 + + 存储设备,外存或辅助存储器 + + 输入输出设备,包括输入设备、输出设备、交互式设备 ++ 按传输速率分类 + + 低速设备:键盘、鼠标 + + 中速设备:打印机 + + 高速设备:磁带、磁盘、光盘 ++ 按信息交换单位分类 + + 块设备,以数据块为单位存储和传输数据,数据块可寻址,如磁盘 + + 字符设备,以字符为单位存放传输设备,如交互式终端、打印机等 ++ 按设备的共享属性分类 + + 独占设备,即临界资源 + + 共享设备,可寻址和随机访问的设备,如磁盘 + + 虚拟设备,通过虚拟技术把一台独占设备变换为若干台逻辑设备 ++ 按设备从属关系分类 + +I/O设备的传输速率涵盖范围很宽,对用户需要隐藏这种差异 + +### 6.1.2 设备控制器 + +> **设备控制器**是计算机中的一个实体 +> +> + 控制一个或多个I/O设备 +> + 实现设备和计算机之间的数据交换 +> + 也成为适配器,是CPU和I/O设备间的一个接口 +> + 通常是一块印刷电路板 + +功能: + ++ 接受和识别CPU命令 ++ 实现数据交换 ++ 标识、报告设备状态 ++ 识别设备地址 ++ 数据缓冲 ++ 差错控制 + +### 6.1.3 I/O通道 + +> **通道**是一种特殊的执行I/O指令的处理机,用于代替处理器实现外部设备的输入/输出操作和管理,实现外部设备与处理器的并行操作。 + +引入目的:解脱CPU对I/O的组织和管理 + +通道类型: + ++ 字节多路通道:以字节为单位,分时共享方式传输数据 ++ 数组选择通道:每个子通道以一组数据为单位 ++ 数组多路通道:结合了前两者优点,能分时并发,传输速率高 + +## 6.2 I/O控制方式 + +I/O控制的方式不断发展,以尽量减少主机对I/O控制的干预 + ++ 可编程I/O-最简单 ++ 中断驱动I/O-最常用 ++ 直接内存访问I/O-改进效率 ++ I/O通道控制方式 + +#### 1.可编程I/O控制方式 + ++ CPU等待I/O完成 ++ 这种模式称为轮询或繁忙等待 + +#### 2.中断驱动I/O + ++ CPU初始化I/O ++ CPU去忙别的事情 ++ I/O完成时,CPU将被中断 ++ CPU处理中断 ++ CPU恢复被中断的程序 + +#### 3.直接内存访问I/O + ++ 中断驱动的明显缺陷是频繁的中断,以字节为单位 ++ 解决方式是使用DMA(Direct Memory Access) + + 数据传输的基本单位是块 + + 使用DMA控制器处理I/O中断 + + 降低CPU响应中断的频率 ++ DMA控制器组成: + + 主机与DMA控制器接口 + + DMA控制器与块设备接口 + + I/O控制逻辑 ++ DMA控制器中设置四类寄存器 + + 命令/状态寄存器(CR) + + 内存地址寄存器(MAR) + + 数据寄存器(DR) + + 数据计数器(DC) + +#### 4.I/O通道控制方式 + +引入: + ++ DMA对许多离散块的读取仍需多次中断 ++ 进一步减少CPU的干预,把对一个数据块的读写干预减少为一组数据块的读写干预 + +在I/O通道控制方式中,CPU只需给出: + ++ 通道程序首址 ++ 要访问的I/O设备 + +## 6.3 缓冲管理 + +> **缓冲**是在通信问题中,为了使通信双方的速度得到匹配而引入的一个中间层次。这个层次比通信中较慢的一方快,而与较快的一方更加匹配。 + +引入: + ++ 缓和CPU与I/O设备速度不匹配的矛盾 ++ 减少对CPU的中断频率 ++ 提高CPU和I/O设备间的并行性 ++ 协调传输数据大小不一致的设备 + +若没有缓冲区: + ++ 磁盘把一块数据送入用户区,花费时间为T ++ CPU对数据进行计算,花费时间为C + +系统对整块数据的处理时间为`T+C` + +问题:通常T>C,CPU等待 + +提供缓冲区: + ++ 磁盘把一块数据送入缓冲区,花费时间T ++ 缓冲区数据送入用户区,花费时间M ++ CPU进行计算,花费时间C + +系统对整块数据处理时间为`max(C,T)+M` + +双缓冲: + ++ 先将数据送到第一个缓冲区 ++ 向第二个缓冲区输送数据同时,CPU计算 ++ 系统处理一块数据时间为`max(C,T)` + +循环缓冲:类似生产者-消费者问题。 + +## 6.4 I/O软件 + +I/O软件是实现I/O管理的软件部分,I/O软件设计目标是改善I/O设备的效率,实现统一标准的I/O设备管理方式。 + +I/O软件的目标: + ++ 设备独立 ++ 统一命名 ++ 错误处理 ++ 缓冲技术 ++ 设备的分配和释放 + +I/O软件普遍采用层次式结构 + ++ 低层次实现与硬件相关操作,并屏蔽硬件的具体细节 ++ 高层次向用户提供一个简洁、统一的接口 + + 每一层具有一个要执行的定义明确的功能和一个与近邻层次定义明确的接口 ++ 不同操作系统的分层是不同的 + +![层次式I/O软件](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/os_10.png) + ++ 中断处理过程:大多I/O是中断驱动 ++ 设备驱动程序 + + 接受由独立软件发来的命令和参数 + + 检查I/O + + 对等待I/O的进程排队 + + 及时响应由控制器和通道发来的中断请求 ++ 设备独立I/O软件 + + 设备独立是OS的一个重要概念 + + 引入逻辑设备和物理设备 + +## 6.5 设备分配 + +引入:系统设备供所有进程共享,为了防止进程对系统资源的无序使用,必须由系统统一进行设备分配。 + +包括:设备、控制器和通道 + +设备分配用数据结构: + ++ 设备控制表DCT ++ 控制器控制表COCT ++ 通道控制表CHCT ++ 系统设备表SDT + +![引入挂起的状态转换](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/os_11.png) + +![引入挂起的状态转换](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/os_12.png) + +## 6.6 磁盘管理 + +> 磁盘存储器是计算机中重要的输入/输出设备,是除内存外最重要的计算机存储器,其优点表现在以下方面: +> +> + 存储容量大 +> + 价格低 +> + 断电后信息不丢失 + +磁盘管理的主要任务: + ++ 分配存储空间 ++ 组织存取方式 ++ 提高存储空间利用率 ++ 提高对磁盘的I/O速度 ++ 采取必要的冗余措施保证文件系统的可靠 + +### 6.6.1 磁盘性能 + +#### 1.磁盘结构 + ++ 磁盘由一组旋转的盘面组成 ++ 每个盘面的**上下**表面有一个个的同心圆 + + 称为磁道 ++ 具有相同半径的磁道称为磁柱 ++ 每个磁道被进一步划分为扇区 + + 扇区是磁盘I/O的基本单位 + + 扇区可以是连续的(逻辑临近=物理临近)或是交错的(逻辑临近!=物理邻近) ++ 磁盘读写过程 + + 将磁头移动到正确的磁道-寻道 + + 等待磁头到达所在删去-旋转 + + 读写数据-数据传输 + +#### 2.寻道时间 + ++ 读写磁头移动到所要求的磁道位置的平均时间——依赖于磁头和磁道的距离 ++ 磁道到磁道的访问时间——磁头移动到相邻磁道所需时间 ++ 平均寻道时间——随机存取中到达要求磁道的平均时间 + +#### 3.旋转延迟和传输时间 + ++ 旋转延迟/等待时间:到达磁道后等待要求扇区转到磁头下方的平均时间 + + 通常是旋转时间的一半:对于7200RPM的磁盘,旋转一周时间为1min/7200转=60000ms/7200转=8.3ms,则旋转延迟约为4.2ms ++ 传输时间:数据从磁盘读出或者向磁盘写入数据需要的时间 ++ 爆发速度:磁盘到达扇面后磁盘驱动器输出或接受数据的最大速度 + +计算: + +平均访问时间=寻道时间+旋转延迟 + +爆发传输速度=每秒旋转次数\*每次旋转经过扇面数\*每个扇面的字节数 + +顺序访问只需寻道一次,之后每个磁道的读取不需寻道,只需计算旋转延迟 + +随机访问每次访问一个扇区都要计算寻道时间+旋转延迟+读取一个扇区的时间 + +### 6.6.2 磁盘调度 + +准则为进程对磁盘的平均访问时间最小 + ++ 先来先服务(FCFS):根据进程访问磁盘的先后顺序 + + 平均访问时间较长 ++ 最短寻道时间(SSTF):选择要访问的磁道与当前所在磁道最近的进程 + + 造成饥饿 ++ 扫描(SCAN)算法:在选择时选择与磁头移动方向相同且最近的进程 + + 缓解了饥饿现象 ++ 循环扫描(CSCAN)算法:磁头总是按一个方向单向移动 + + 磁臂黏着 ++ NStepSCAN:按FCFS分配队列,在处理队列时使用SCAN算法 + +--- + +# 第七章 文件系统 + +为什么要使用文件系统? + ++ 内存容量有限,不持久,难以共享 ++ 选择存储在磁盘上 + + 持久,可共享,容量大 + + 对于普通用户使用磁盘不容易——对磁盘进行抽象,构造文件系统 + +## 7.1 文件系统的概念 + +> 文件系统是操作系统对磁盘的抽象 +> +> 使得用户不需要了解以下细节: +> +> + 信息被存储在哪里 +> + 信息如何保存 +> + 磁盘实际上如何工作 + +![文件系统](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/os_13.png)) + ++ 文件系统的特征: + + 存储大量数据 + + 进程结束不会影响文件的持续存在 + + 多个进程可以同时访问一个文件 + + 文件是由文件各标志的一组信息的集合 + +### 7.1.1 文件 + +> 文件是由文件名标识的一组信息的集合。 + +命名:用户提供一个符号名→磁盘上的映射位置 + +文件可以带扩展名,传递有关文件的信息 + +另一种方式则是按内容寻址 + +### 7.1.2 文件类型 + ++ 按照文件用途分类 + + + 系统文件 + + 用户文件 + + 库文件 + ++ 按照文件中的数据形式进行分类 + + + 源文件 + + 可执行文件 + + 视频文件 + + etc. + + 操作系统给能够识别和莪支持多少种类的数据文件,是衡量操作系统应用范围的重要标志 + + 部分操作系统将文件的数据类型隐含在扩展名中(如MS-DOS) + + Linux、Unix则没有隐含文件类型,扩展名仅仅用于帮助用户识别 + +### 7.1.3 文件访问 + ++ 两种文件访问类型:随机访问、顺序访问 + +### 7.1.4 文件属性 + +文件属性并不属于文件内容,但文件属性是操作系统管理和控制文件,是实现文件保护的重要依据。 + +要管理和控制文件,不能只通过文件名,还要通过文件的其他属性 + ++ 文件标识符 ++ 文件拥有者 ++ 文件类型 ++ 文件的存取控制 ++ 文件定位(location) ++ 文件大小 ++ 文件保护 ++ 文件日期和时间 + +## 7.2 文件结构* + +> 文件结构是指文件中信息的构造和组织方式 + ++ 文件的逻辑结构 + + + 字节流结构形式:在文件中按字节个数/特殊符号分界 + + + 记录结构形式 + + 基本单位:逻辑记录 + + 逻辑记录是文件内独立的最小单位 + + 又可以按照记录的排列顺序不同分为: + + + 连续文件:文件按照记录生成的时间顺序连续排列 + + 索引文件:对文件建立一个索引表,文件中的每条记录在索引中有响应的表项 + + 顺序索引文件 + +## 7.3 文件目录 + +**文件目录本身也是文件** + ++ 目录包含了一组文件的映射 + + 名称→文件标题的磁盘块 + + 通常可以用一个简单的数组实现,数组存放着文件夹的内容 + + ls/dir命令查看目录内容 ++ 可以用相同的方式对待目录和文件 ++ 目录里可以存放目录 ++ 根目录是系统文件的总起点 + +**路径名:**一种指定树中的文件名称的方式 + ++ 绝对路径 ++ 相对路径 + +**链接**:快捷方式 + ++ 链接允许一个文件在多个地方出现 ++ 指定一个文件到路径名之间的链接 + +## 7.4 文件系统的实现 + +### 7.4.1 文件系统的布局 + ++ 文件系统储存在磁盘上 ++ 大多数磁盘被分区 ++ 每个分区有自己的文件系统 + +磁盘的第0个扇区为主引导记录MBR + ++ MBR用于启动计算机 ++ MBR后面紧接着就是磁盘分区表 + + 给出每个分区的起始和结束地址 + + 一个分区标记为激活状态,称为主分区 + + 主分区最前面是引导记录 ++ 计算机启动时由BIOS读写MBR ++ MBR定位系统主分区,加载引导记录 ++ 引导记录加载操作系统映像 ++ 引导记录块之外的内容因系统情况而异 + +### 7.4.2 文件在磁盘上的存放方式 + ++ 连续存放方式 + + + 存储在一片连续的磁盘空间 + + 用户需实现声明文件大小 + + 文件定位:起始块+文件尺寸 + + 会导致磁盘碎片 + + 优点: + + + 快速顺序访问 + + 易于随机访问 + + 缺点: + + + 碎片 + + 大多系统文件采用顺序存储的方式储存以加速访问 + ++ 链表方式 + + + 保存每个文件的所有磁盘块的链表 + + 磁盘块不需要临接 + + 优点: + + + 没有磁盘碎片空间被浪费 + + 方便文件的增长、收缩 + + 缺点: + + + 随机访问速度慢 + + 链表的存放需要存储空间 + + 链表方式使用内存中的文件分配表(FAT)解决存放需要空格键的问题 + ++ 索引方式 + + + 为每个文件建立索引表 + + 前提条件:文件的逻辑记录大小等于物理块大小 + + 用户先宣称文件大小 + + 分配一个含有相应数量指针空间的文件头,即索引 + + 类似于页表 + + 优点: + + + 文件易于增长 + + 易于随机访问 + + 缺点: + + + 顺序访问效率不高 + + 如果数据块数超过索引头预留的指针数时,文件增长不容易 + + 解决:使用多级索引 + ++ 多级索引,增加空间,但访问次数高,效率降低 + +### 7.4.3 目录实现 + ++ 文件夹包含了里面文件的记录项 ++ 主要功能:提供文件名到文件地址的映射 ++ 哪里可以保存文件的属性: + + 目录 + + 索引项 + +文件共享:树/链接 + +### 7.4.4 磁盘空间管理: + ++ 文件被正常存储在磁盘上 ++ 磁盘空间管理很重要 ++ 类似于内存空间管理 + + 连续分配 + + 非连续分配:文件分页,磁盘划分为磁盘块 + +### 7.4.5 闲置空间管理 + +#### 1.空闲表法 + +空闲表主要适合连续文件,系统通过一个空闲表管理磁盘的所有空闲分区。 + +为文件分配空闲区的方法与内存的空闲区分配类似(首次适应法,最佳适应法) + +可用于虚拟存储器管理的外存对换空间的分配 + +#### 2.空闲链表法 + +属于非连续分配方式。要在磁盘的每个空闲块中设置一个指向下一个空闲块的指针。 + +优点:适合文件动态增长和收缩 + +缺点:效率较低 + +#### 3.位视图法 + +用若干个字节构成一个表,表中每一个字位表示一个磁盘块的使用情况。 + +为了防止用户占用太多磁盘空间:磁盘配额 + +## 7.5 文件系统的性能* + ++ 文件系统可靠性 + + 一致性 + + 持久性 ++ 文件系统性能 ++ 文件保护机制 diff --git a/docs/ComputerOrganization.md b/docs/ComputerOrganization.md new file mode 100644 index 0000000..8e8b53d --- /dev/null +++ b/docs/ComputerOrganization.md @@ -0,0 +1,1818 @@ +*written by PeterAlbus,Copyright © 2021 - SHOU 1951123 Hong Wu* + +--- + +# 附录 常见缩写及解释 + ++ ALU 算术逻辑单元 ++ CU 控制单元 ++ ACC 运算器的累加器 ++ MAR 存储器地址寄存器 ++ MDR 存储器数据寄存器 ++ MQ 运算器的乘商寄存器 ++ X 操作数寄存器 ++ PC 程序计数器 ++ IR 指令寄存器 ++ MIPS 百万条指令每秒 ++ CPI 执行一条指令所需的时钟周期 ++ FLOPS 浮点运算每秒 ++ MBPS 兆字节每秒 ++ DMA 直接存储器存取 ++ BS 总线忙 ++ BR 总线请求 ++ BG 总线同意 ++ MROM 掩模型只读存储器 ++ PROM 可编程只读存储器 ++ EPROM 可擦除可编程只读存储器 ++ EEPROM 用电可擦除可编程只读存储器 ++ MCT 存取周期 ++ CS(上划线)片选信号(低电平有效) ++ WE(上划线)写允许信号(低电平为写,高电平为读) ++ V CC 代表电源 ++ GND 代表接地端 ++ RAS(上划线) 行地址选通 ++ CAS(上划线) 列地址选通 ++ CCW 通道指令 ++ DBR 数据缓冲寄存器 ++ INTR 中断请求触发器 ++ MASK 屏蔽触发器 ++ AR 主存地址寄存器 ++ WC 字计数器 ++ BR 数据缓冲寄存器 ++ DAR 设备地址寄存器 ++ DREQ 向DMA接口提出申请 ++ HRQ 发出总线使用权的请求信号 ++ RISC 精简指令系统计算机 ++ CISC 复杂指令系统计算机 ++ NOP 空操作 ++ HLP 停机 ++ RET 子程序返回 ++ IRET 中断返回 ++ SP 堆栈指针 ++ FLASH MEMORY 闪速存储器 + +# 第一章 计算机系统概论 + +## 1.1 计算机系统简介 + +### 1.1.1 计算机的软硬件概念 + +计算机系统由“硬件”和“软件”两大部分组成。 + +> **硬件**是指计算机的实体部分,它由看得见摸得着的各类电子元器件,各类光、电、机设备的事物组成,如主机、外部设备等。 + +> 所谓**软件**,它看不见摸不着,由人们实现编制的具有各类特殊功能的程序组成。 + +计算机的软件又可以分为两大类:系统软件和应用软件。 + +### 1.1.2 计算机的层次结构 + +![五级层次结构](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_01.png) + +## 1.2 计算机的基本组成 + +### 1.2.1 冯诺依曼计算机的特点 + ++ 由运算器、存储器、控制器、输入设备和输出设备五大部件组成 ++ 指令和数据以同等地位存放于存储器内 ++ 指令和数据均用二进制表示 ++ 指令由操作码和地址码组成,操作码表示操作性质,地址码表示操作数位置 ++ 指令在存储器内按顺序存放,通常按顺序执行,特定条件下也可改变执行顺序 ++ 机器以**运算器**为中心 + +### 1.2.2 现代计算机硬件框图 + ++ 以**存储器**为中心 + +![存储器为中心](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_03.png) + ++ 运算器用来完成算术运算和逻辑运算,并将运算的中间结果暂存在运算器内 ++ 存储器用来存放数据和程序 ++ 控制器用来控制、指挥程序和数据的输入、运行以及处理运算结果 ++ 输入设备用来将人们熟悉的信息形式转换为机器能识别的信息形式 ++ 输出设备可将机器运算结果转换为人们熟悉的信息形式 + +![现代计算机硬件框图](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_02.png) + +## 1.3 计算机硬件的主要技术指标 + ++ 机器字长 ++ 存储容量 ++ 运算速度 + +--- + +# 第二章 计算机的发展及应用 + +## 2.1 计算机的发展史 + +### 2.1.1 计算机的产生和发展 + ++ 第一台电子计算机:1946 美国 ENIAC + ++ 现代计算机产生的驱动力:需求+技术发展 + ++ 硬件技术的发展: + + 电子管(第一代计算机)→晶体管(第二代计算机)→中小规模集成电路(第三代计算机,几十/上百个元件)→大规模集成电路(上千个元件)→超大规模集成电路(一片IC芯片上能容纳数万个以上元件) + + 计算机的更新换代以**电子器件**为依据 + +### 2.1.2 微型计算机的出现和发展 + +微处理器芯片 1971年(4位、8位、...、64位) + +存储器芯片 1970年 + +Moore定律:微芯片上集成的晶体管数目每三年翻两番 + +### 2.1.3 软件计数的兴起和发展 + +#### 1.各种语言 + +机器语言-面向机器 + +汇编语言-面向机器 + +高级语言-面向问题 + ++ FORTRAN 科学计算 ++ PASCAL 结构化程序设计 ++ C++ 面向对象 ++ Java 适应网络环境 + +#### 2.系统软件 + ++ **语言处理程序**:汇编程序,编译程序,解释程序 ++ **操作系统**:DOS UNIX Windows ++ **服务型程序**:装配 调试 诊断 排错 ++ **数据库管理系统**:DB和DBMS ++ **网络软件** + +#### 3.软件发展的特点 + ++ 开发周期长 ++ 制作成本昂贵 ++ 检测软件产品质量的特殊性 + +## 2.2 计算机的应用 + ++ 科学计算和数据处理 ++ 工业控制和实时控制 ++ 网络技术 + + 电子商务 + + 网络教育 ++ 虚拟现实 ++ 办公自动化和管理信息系统 ++ CAD(Computer Aided Desgine)/CAM(Computer Aided Manufacturing)/CIMS(Computer Intergrated Manufacturing System) ++ 多媒体技术 ++ 人工智能 + +## 2.3 计算机的展望 + +替代传统的硅芯片:光计算机、DNA生物计算机、量子计算机 + +--- + +# 第三章 系统总线 + +## 3.1 总线的基本概念 + +> **总线**(bus)是连接多个部件的信息传输线,是各部件共享的信息传输介质。 + +使用总线的原因:I/O设备不断增多,人们希望随时增添或减撤设备**。** + +**总线结构的举例**: + ++ 单总线结构框图 + + ![单总线](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_04.png) + ++ 存储器为中心的双总线 + + ![双总线](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_05.png) + +## 3.2 总线的分类 + ++ 片内总线:芯片内部的总线 + ++ 系统总线:计算机各部位之间的信息传输线 + + + 数据总线:双向,与机器字长,存储字长有关 + + 地址总线:单向,与存储地址,I/O地址有关 + + 控制总线:有出(存储器读写、总线允许、中断确认)、有入(中断请求、总线请求) + ++ 通信总线:用于计算机系统之间或计算机系统与其他系统之间的通信 + + 传输方式: + + + 串行通信总线 + + 并行通信总线 + +## 3.3 总线特性及性能指标 + +### 3.3.1 总线特性 + +总线的物理实现:印制在电路板上 + +![总线物理实现](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_06.png) + ++ 机械特性:尺寸、形状、管脚数及排列顺序 ++ 电气特性:传输方向和有效的电平范围 ++ 功能特性:每根传输线的功能(地址、数据、控制) ++ 时间特性:任意一根线在什么时间内有效 + +### 3.3.2 总线的性能指标 + ++ **总线宽度**:数据线根数 ++ **总线带宽**:每秒传输的最大字节数(MBps) ++ **时钟同步/异步**:同步/不同步 ++ **总线复用**:地址线与数据线服用 ++ **信号线数**:地址线、数据线和控制线的综合 ++ **总线控制方式**:并发、自动、仲裁、逻辑、计数 ++ 其他指标:**负载能力** + +### 3.3.3 总线标准 + +> **总线标准**,可视为系统与各模块,模块与各模块之间的一个互联的标准界面。 + +采用总线标准可以为计算机接口的软硬件设计提供方便。 + +流行的总线标准: + ++ ISA ++ EISA ++ VESA(LV-BUS) ++ PCI ++ AGP ++ RS-232 ++ USB + +## 3.4 总线结构 + ++ 单总线结构:已在-3.1 总线的基本概念-处展示 + + 这类总线通常被小型或微型计算机使用 + ++ 多总线结构 + + + 双总线结构 + + ![总线结构](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_07.png) + + + 三总线结构 + + ![总线结构](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_08.png) + + + 三总线结构的又一形式 + + ![总线结构](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_09.png) + + + 四总线结构 + + ![总线结构](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_10.png) + ++ 总线结构举例(P55) + + + 传统卫星总线结构 + + VL-BUS局部总线结构 + + PCI总线结构 + + 多层PCI总线结构 + +## 3.5 总线控制 + +### 3.5.1 总线判优控制 + +> 总线上的设备分为主设备和从设备。 +> +> **主设备**:对总线有控制权。 +> +> **从设备**:响应从设备发来的总线命令 +> +> 当多个主设备要使用总线时,就由总线控制器的**判优**、仲裁逻辑按一定的优先等级顺序确定哪个主设备能使用总线。 + +总线判优控制 + ++ 集中式 + + 链式查询 + + 离控制部件最近的设备有最高的优先权 + + 对电路故障敏感 + + 使用2根线确定总线控制权 + + 计数器定时查询 + + 计数可以从0开始,也可以从上次结束的地方开始(会导致优先级不同) + + 电路故障不如链式查询敏感,但增加了设备地址线,控制也较复杂 + + 使用$log_2n$条线确定总线控制权 + + 独立请求方式 + + 响应速度快,优先次序灵活 + + 控制线数量多,控制也更复杂 + + 使用2n根线确定总线控制权 ++ 分布式 + +![总线判优控制](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_11.png) + +### 3.5.2 总线通信控制 + ++ **目的**:解决通信双方协调配合问题 + ++ 总线传输周期: + + + 申请分配阶段:主模块申请,总线仲裁 + + 寻址阶段:主模块向从模块给出地址和命令 + + 传数阶段:主模块和从模块交换数据 + + 结束阶段:主模块撤销有关信息 + ++ 总线通信的四种方式 + + + 同步通信:由统一时标控制数据传送 + + 异步通信:允许各模块速度的不一致性 + + 不互锁:从设备没有反馈 + + 半互锁:等待从设备有反馈后主设备才能撤销请求 + + 全互锁:等待从设备有反馈后主设备才能撤销请求,等待主设备撤销请求后才能撤销回答 + + 半同步通信:若检测到WAIT信号,插入时钟(等待)周期(同步、异步结合) + + 分离式通信:充分挖掘系统总线每个瞬间的潜力 + + 子周期1:主模块申请占用总线,使用后放弃总线使用权 + + 子周期2:从模块申请占用总线传输数据 + + 前三种通信的共同点: + + + 首先申请总线 + + 主模块通过总线向从模块发送请求 + + 从模块准备数据 + + 从模块传输数据 + + 在准备数据时总线空闲 + + 分离式通信: + + 各模块有权申请占用总线 + + 异步通信 + + 各模块准备数据时都不占用总线 + + **充分提高了总线的有效占用** + +--- + +# 第四章 存储器 + +## 4.1 概述 + +### 4.1.1 存储器的分类 + +#### 1.按存储介质分类 + ++ **半导体存储器** TTL,MOS (易失) ++ **磁表面存储器** 磁头,载磁体 (非易失) ++ **磁芯存储器** 硬磁材料,环状元件 (非易失) ++ **光盘存储器** 激光,磁光材料 (非易失) + +#### 2.按存取方式分类 + ++ 存取时间与物理地址无关(随机访问) + + 随机存储器 + + 只读存储器 ++ 存取时间与物理地址有关(串行访问) + + 顺序存储存储器 磁带 + + 直接存取存储器 磁盘 + +#### 3.按在计算机中的作用分类 + ++ 主存储器 + + RAM + + 静态RAM + + 动态RAM + + ROM + + MROM(掩模式只读存储器) + + PROM(可编程只读存储器) + + EPROM(可擦编程只读存储器) + + EEPROM(带电可擦可编程只读存储器) ++ Flash Memory ++ 高速缓冲存储器(Cache) ++ 辅助存储器 + +### 4.1.2 存储器的层次结构 + +#### 1.存储器三个重要特性的关系 + +![三个重要特性的关系](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_12.png) + +#### 2.缓存-主存层次和主存-辅存层次 + +缓存-主存:速度 + +主存-辅存:容量 + +## 4.2 主存储器 + +### 4.2.1 概述 + +#### 1.主存的基本组成 + +![主存的基本组成](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_13.png) + +#### 2.主存和CPU的联系 + +![主存和CPU的联系](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_14.png) + +#### 3.主存中存储单元地址的分配 + +> 字节:8位二进制数 +> +> 字:根据机器字长不同,用n个字节表示一个字 + ++ 一个字中的高位字节地址表示字地址 + + | 字地址 | 字节地址 | 字节地址 | 字节地址 | 字节地址 | + | :----: | :------: | :------: | :------: | :------: | + | 0 | 0 | 1 | 2 | 3 | + | 4 | 4 | 5 | 6 | 7 | + | 8 | 8 | 9 | 10 | 11 | + ++ 一个字中的低位字节地址表示字地址 + + | 字地址 | 字节地址 | 字节地址 | + | :----: | :------: | :------: | + | 0 | 1 | 0 | + | 2 | 3 | 2 | + | 4 | 5 | 4 | + +按字寻址,需要拿出n根地址线(2^n=字节数目),其余位标识字地址,寻址范围为2^(地址线数目-n) + +#### 4.主存的技术指标 + ++ 存储容量 ++ 存储速度 + + 存取时间 + + 存取周期:连续两次独立的存储器操作所需的最小间隔时间 ++ 存储器的带宽 位/秒 + +### 4.2.2 半导体存储芯片简介 + +#### 1.基本结构 + +![半导体存储芯片](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_15.png) + +``` +芯片容量=2^地址线条数*数据线位数 +``` + +片选线CS/CE,读写控制线WE(Write Enable),OE(Output Enable) 上划线代表:低电平有效 + +#### 2.半导体存储芯片的译码驱动方式 + ++ 线选法:仅一个地址译码器,选择对应的字线,容量大时不合适 + ++ 重合法: + + ![重合法](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_16.png) + +### 4.2.3 随机存取存储器(RAM) + +#### 1.静态RAM(SRAM) + +> 静态RAM使用触发器原理储存信息,在掉电时丢失全部信息。 + ++ 基本电路 + + ![RAM1](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_17.png) + ++ 读操作 + + ![RAM2](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_18.png) + ++ 写操作 + + ![RAM3](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_19.png) + ++ 静态RAM读、写时序 + + ![RAM4](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_20.png) + + ![RAM5](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_21.png) + +#### 2.动态RAM(DRAM) + +> 动态RAM靠电容存储电荷的原理储存信息,电容上有足够电荷表示1,无足够电荷则表示0。电荷不能长久维持,因此必须在2ms内对所有存储单元恢复一次原状态,这个过程称为再生或刷新。 + +基本单元电路: + +![RAM6](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_22.png) + +读出信息与原存信息相反 + +写入信息与输入信息相同 + ++ 动态RAM刷新 + + 刷新与行地址有关 + + + 集中刷新:每隔一段时间刷新全部 + + 分散刷新:一个存取周期包含读写+刷新 + + 异步刷新:每隔一段时间刷新一行,可将刷新安排在指令译码阶段 + +#### 3.动态RAM和静态RAM的比较 + +目前,动态RAM的应用比静态RAM广得多。 + +| | DRAM | SRAM | +| -------- | ------ | ------ | +| 存储原理 | 电容 | 触发器 | +| 刷新 | 有 | **无** | +| 集成度 | **高** | 低 | +| 芯片引脚 | **少** | 多 | +| 功耗 | **小** | 大 | +| 价格 | **低** | 高 | +| 速度 | 慢 | **快** | + +### 4.2.4 只读存储器(ROM) + +#### 1.掩模ROM(MROM) + +行列选择线交叉处有MOS管为1,否则为0 + +#### 2.PROM(一次性编程) + +通过熔丝,熔丝断为0,未断为1 + +#### 3.EPROM(多次性编程) + +N型沟道浮动栅MOS电路:写入:电压,擦除:紫外线 + +#### 4.EEPROM(多次性编程) + ++ 电可擦写 ++ 局部擦写 ++ 全部擦写 + +#### 5.Flash Memory(闪速型存储器) + +比EEPROM快,具备RAM功能 + +### 4.2.5 存储器与CPU的连接 + +#### 1.存储器容量的扩展 + ++ 位扩展(增加存储字长) + + 用2片1K\*4位的存储芯片组成1K\*8位的存储器 + ++ 字扩展 + + 用2片1K\*8位的存储芯片组成2K\*8位的存储器 + ++ 字、位扩展 + + 上面两者结合而成 + +#### 2.存储器与CPU的连接 + ++ 地址线的连接 ++ 数据线的连接 ++ 读/写命令线的连接 ++ 片选线的连接 ++ 合理选择存储芯片 ++ 其他:时序、负载 + +参考书P94 例4.1/4.2 + +### 4.2.6 存储器的校验 + +#### 1.编码的最小距离 + +> 编码的最小距离,是指在一种编码系统中,任意两组合法代码之间二进制位数的最少差异。 + +例如,假如一个编码系统,合法编码有1111,1100,0000,则最小编码距离为2。 + +编码的纠错、检错能力与编码的最小距离有关。 + +设L为编码的最小距离,D为检测错误的位数,C为纠正错误的位数,则: + +```c +L-1=D+C(D>=C) +``` + +#### 2.汉明码 + +> “汉明码”是一种“错误纠正码”,可以用来检测并且纠正数据从发送端发往接收端中发生的错误 + +汉明码是具有一位纠错能力的编码。 + +若原值有n位,汉明码的组成需要添加k位检测位 +$$ +2^k \geq n+k+1 +$$ +检测位的位置为2^i(i=0,1,2,3...) + +添加检测位后分组,每个检测位对应第(i+1)组: + ++ 对于检测位2^i,将所有数的位置转换为2进制 ++ 如有7位数字,则分别为001位、010位、011位.... ++ 将所有第i+1位为1的数字分到该组,如检测为为2^0=1,则001,011,101,111(第1,3,5,7个数)属于该组 + +分组后进行校验,分为奇校验与偶校验 + +对每组进行检测,要求每组的数字之和为奇数/偶数(对于二进制来说,即拥有奇数/偶数个1)(可通过对所有数进行异或运算,若结果为0则为偶数,结果为1则为奇数) + +若检测出错,通过找到多个出错的组的公共位即可找到出错的位置 + +### 4.2.7 提高访存速度的措施 + ++ 采用高速器件 ++ 采用层次结构Cache-主存 ++ 调整主存结构 + + 单体多字系统 + + 多体并行系统 + + 高位交叉 各个体并行工作 + + 低位交叉 在不改变存储器周期的前提下,增加存储器带宽 + + 存储器控制部件 + + 高性能存储芯片 + + SDRAM CPU无需等待,在系统时钟的控制下进行读出和写入 + + RDRAM 主要解决了存储器带宽问题 + + 带Cache的DRAM + +## 4.3 高速缓冲器 + +### 4.3.1 概述 + +#### 1.问题的提出 + +避免CPU“空等”的现象 + +解决CPU和DRAM的速度差异 + +![CACHE](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_23.png) + +#### 2.Cache的工作原理 + ++ 主存和缓存按块存储,块的到校相同 + ++ 命中与未命中 + + + 命中:主存块调入缓存,主存块与缓存建立了对应关系 + + 用 标记记录 与某缓存块建立了对应关系的 主存块号 + + 未命中:未建立对应关系 + ++ 命中率 + + + CPU欲访问的信息在Cache中的比率 + + 命中率 与 Cache 的 **容量** 与 **块长** 有关 + ++ Cache-主存系统的效率 + $$ + e=\frac{访问Cache的时间}{平均访问时间} + $$ + +#### 3.Cache的基本结构 + + ![Cache结构](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_24.png) + +#### 4.Cache的读写操作 + ++ 读: + + ![CACHE读](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_25.png) + ++ 写:保证CACHE和主存的一致性 + + + 写直达法 + + 写操作时既写入Cache又写入主存 + + 写操作时间就是访问主存的时间,更新策略容易时间 + + + 写回法 + + 只写入Cache,写操作时间就是访问Cache的时间 + + Cache被替换的块需要写回主存,增加了Cache 的复杂性 + +#### 5.Cache的改进 + ++ 增加Cache级数 ++ 统一缓存和分立缓存 + +### 4.3.2 Cache-主存地址的映射 + +#### 1.直接映射 + +每个缓存块对应多个主存块 + +缓存标记储存的主存块,比较器检测是否命中 + +#### 2.全相联映射 + +主存中的任意一块可以映射到缓存中的任意一块 + +#### 3.组相联映射 + +某一主存块可以映射到缓存的某一组的任意一块(直接映射和全相联映射结合) + +### 4.3.3 替换算法 + ++ FIFO ++ LRU + +## 4.4 辅助存储器 + ++ 特点:不直接与CPU交换信息 ++ 硬磁盘 ++ 软盘 ++ 光盘 + +--- + +# 第五章 输入输出系统 + +## 5.1 概述 + +### 5.1.1 输入输出系统的发展概况 + ++ 早期:分散连接,CPU和I/O设备串行工作,程序查询方式 ++ 接口模块和DMA阶段 + + 总线连接 + + CPU和I/O设备并行工作 + + 中断方式 + + DMA方式 ++ 具有通道结构的阶段 ++ 具有I/O处理机的阶段 + +### 5.1.2 输入输出系统的组成 + ++ I/O软件 + + I/O指令 CPU指令的一部分 + + 通道指令 通道自身的指令 ++ I/O硬件 + + 设备-I/O接口 + + 设备-设备控制器-通道 + +### 5.1.3 I/O设备与主机的联系方式 + ++ I/O设备编址方式 + + + 统一编址 用取数、存数指令 + + 不统一编址 有专门的I/O指令 + ++ 设备选址 + + 用设备选择电路识别是否被选中 + ++ 传送方式 + + + 串行 + + 并行 + ++ 联络方式 + + + 立即响应 + + 异步工作采用应答信号 + + 同步工作采用同步时标 + ++ 连接方式 + + + 辐射式连接 + + 每个设备都配有一套控制线路和一组信号线 + + 不便于增删设备 + + + 总线连接 + + 便于增删设备 + +### 5.1.3 I/O设备与主机信息传送的控制方式 + ++ 程序查询方式:CPU和I/O串行工作,踏步等待 ++ 程序中断方式:CPU和I/O设备并行工作 + + I/O准备:CPU完成自身任务 + + 与主机交换信息:CPU暂停先行程序 ++ DMA方式:CPU和I/O设备并行工作 + + 主存和I/O之间有一条直接数据通道 + + 不中断现有程序 + + 周期挪用 + +![三种方式的比较](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_26.png) + +## 5.2 I/O设备 + +### 5.2.1 概述 + +> 中央处理器和主存构成了主机,除主机外的大部分硬件设备都可称为I/O设备或外部设备,或外围设备,简称外设。 + +外部设备大致分为3类: + ++ **人机交互设备:**键盘、鼠标、打印机、显示器 ++ **计算机信息存储设备:**磁盘、光盘、磁带 ++ **机-机通信设备:**调制解调器等 + +### 5.2.2 输入设备 + ++ 键盘 + + 按键 + + 判断哪个键被按下 + + 将此键翻译成ASCII码 ++ 鼠标 + + 机械式 金属球,电位器 + + 光电式 光电转换器 ++ 触摸屏 + +### 5.2.3 输出设备 + ++ 显示器 + + 字符显示 字符发生器 + + 图形显示 主观图像 + + 图像显示 客观图像 ++ 打印机 + + 击打式 点阵式 + + 非击打式 激光、喷墨 + +### 5.2.4 其他I/O设备 + ++ A/D,D/A转换器(数字/模拟信号转换器) ++ 终端-由键盘和显示器组成 ++ 汉字处理 + +### 5.2.5 多媒体技术 + +> 多媒体(Multimedia)是多种[媒体]()的[综合](),一般包括文本,声音和图像等多种媒体形式。 +> +> 在计算机系统中,多媒体指组合两种或两种以上媒体的一种人机交互式[信息交流]()和[传播媒体]()。使用的媒体包括文字、图片、照片、声音、动画和影片,以及程式所提供的互动功能。 + ++ 多媒体计算机的关键技术 + + 视频和音频数据的压缩与解压缩技术 + + 多媒体专用芯片 + + 大容量存储器 + + 适用于多媒体技术的软件 + +## 5.3 I/O接口 + +### 5.3.1 概述 + +为什么要放置接口? + ++ 实现设备的选择 ++ 实现数据缓冲达到速度匹配 ++ 实现数据串——并格式转换 ++ 实现电平转换 ++ 传送控制命令 ++ 反映设备的状态 + +### 5.3.2 接口的功能和组成 + +#### 1. 总线连接方式的I/O接口电路 + ++ 设备选择线 ++ 数据线 ++ 命令线 ++ 状态线 + +![I/O接口电路](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_27.png) + +#### 2.接口的功能和组成 + +| 功能 | 组成 | +| :----------: | :---------------: | +| 选址 | 设备选择电路 | +| 传送命令 | 命令寄存器/译码器 | +| 传送数据 | 数据缓冲寄存器 | +| 反映设备状态 | 设备状态标记 | + ++ 完成触发器D ++ 工作触发器B ++ 中断请求触发器INTR ++ 屏蔽触发器MASK + +### 5.3.3 接口类型 + ++ 按数据传送方式分类 + + 并行接口 + + 串行接口 ++ 按选择的灵活性 + + 可编程接口 + + 不可编程接口 ++ 通用性 + + 通用接口 + + 专用接口 ++ 控制方式(程序查询方式没有接口) + + 中断接口 + + DMA接口 + +## 5.4 程序查询方式 + +### 5.4.1 程序查询流程 + +单个和多个设备的程序查询流程: + +![程序查询流程](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_28.png) + +### 5.4.2 程序流程 + +![程序流程](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_29.png) + +### 5.4.3 接口电路 + +![接口电路](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_30.png) + +## 5.5 程序中断方式 + +### 5.4.1 中断的概念 + +> **中断**是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行。 + +### 5.4.2 中断的产生 + +CPU启动I/O设备后,继续执行主设备,I/O设备在数据准备完成后发起中断,CPU处理I/O。 + +CPU与I/O设备并行工作 + +### 5.4.3 程序中断方式接口电路 + +#### 1. 配置中断请求触发器(INTR)和中断屏蔽触发器(MASK) + +INTR=1 CPU发起中断请求 + +MASK=1 中断被屏蔽 + +D: 完成触发器,代表I/O准备完成 + +#### 2.排队器 + ++ 硬件:在CPU内或接口电路中 + ++ 软件 + +#### 3.中断向量地址形成部件 + ++ 由软件产生 ++ 硬件向量法:硬件产生向量地址,再由向量地址找到入口地址 + +#### 4.程序中断方式接口电路的基本组成 + +![三种方式的比较](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_31.png) + +### 5.4.4 I/O中断处理过程 + ++ CPU响应中断的条件和时间 + + + 条件:EINT允许中断触发器=1 + + + 时间:D=1且MASK=0 + + 在每条指令执行阶段的结束前CPU发送中断查询信号(INTR置1) + +### 5.4.5 中断服务程序的流程 + +#### 1.流程 + ++ 保护现场 + + 程序断点的保护 + + 寄存器内容的保护 ++ 中断服务 ++ 恢复现场 ++ 中断返回 + +#### 2.单重中断和多重中断 + +单重中断:不允许中断现行的中断服务程序 + +多重中断:允许级别更高的中断源中断现行的中断服务车光绪 + +## 5.6 DMA方式 + +### 5.6.1 DMA方式的特点 + ++ DMA通过DMA接口与主存直接交换数据,而不需要经过CPU ++ DMA与主存交换数据的三种方式 + + 停止CPU访问主存:控制简单、CPU处于不工作状态、未充分发挥CPU对主存的利用率 + + 周期挪用:DMA请求时CPU没有访存则成功,DMA与CPU同时请求访存时优先DMA,否则等待CPU + + DMA与CPU交替访问:工作周期中专为DMA分出时间,不需要建立申请和归还总线的使用权 + +### 5.6.2 DMA接口的功能和组成 + +#### 1.DMA接口功能 + ++ 向CPU申请DMA传送 ++ 处理总线控制权的转交 ++ 管理系统总线、控制数据传送 ++ 确定数据传送的首地址和长度 ++ DMA传送结束时,给出完成信号 + +#### 2.DMA接口组成 + +![DMA](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_32.png) + +### 5.6.3 DMA的工作过程 + +#### 1.DMA传送过程 + ++ 预处理 ++ 数据传送 ++ 后处理 + + 校验数据正确性 + + 是否继续使用DMA + + **由中断服务程序完成** + +#### 2.DMA接口与系统的连接方式 + ++ 具有公共请求线的DMA请求 ++ 独立的DMA请求 + +#### 3.DMA方式与程序中断方式的比较 + +| | 中断方式 | DMA方式 | +| ------------ | ------------ | ------------ | +| 数据传送 | 程序 | 硬件 | +| 响应时间 | 指令执行结束 | 存取周期结束 | +| 处理异常情况 | 能 | 不能 | +| 中断请求 | 传送数据 | 后处理 | +| 优先级 | 低 | 高 | + +### 5.6.4 DMA接口的类型 + ++ 选择型:物理上连接多个设备,逻辑上只连接一个 ++ 多路型:物理上连接多个,逻辑上也允许多个同时工作 + + 原理:并发 + +--- + +# 第六章 计算机的运算方法 + +## 6.1 无符号数和有符号数 + +### 6.1.1 无符号数 + +寄存器的位数反映无符号数二点表示范围 + +8位:0~255 + +16位:0~65535 + +### 6.1.2 有符号数 + +#### 1.机器数与真值 + +| 真值 | 机器数 | +| :-----: | :----------------------: | +| +0.1011 | 0,1011[小数点在符号位后] | +| -1100 | 1,1100[小数点在末尾] | + +#### 2.原码表示法 + +整数: +$$ +\begin{equation}[x]_原= +\begin{cases} +0,x& 2^n>x \geq 0 \\ +2^n-x& 0\geq x >-2^n +\end{cases} +\end{equation} +$$ +小数: +$$ +\begin{equation}[x]_原= +\begin{cases} +x& 1>x \geq 0 \\ +1-x& 0\geq x >-1 +\end{cases} +\end{equation} +$$ +即正数符号位为0,负数符号位为1,用逗号将符号位和数值部分隔开 + +原码的特点:简单、直观 + +但用原码对负数作加法时会出现问题 + +解决方法:找一个与负数等价的正数来代替这个负数 + +#### 3.补码表示法 + ++ 一个负数加上 “模” 即得该负数的补数 ++ 一个正数和一个负数互为补数时,它们绝对值之和即为 模 数 ++ 正数的补数即为其本身 + +整数(n为整数位数): +$$ +\begin{equation}[x]_补= +\begin{cases} +0,x& 2^n>x \geq 0 \\ +2^{n+1}+x& 0\geq x >-2^n +\end{cases} +\end{equation} +$$ +小数: +$$ +\begin{equation}[x]_补= +\begin{cases} +x& 1>x \geq 0 \\ +2+x& 0\geq x >-1 +\end{cases} +\end{equation} +$$ +**求补码的快捷方式**:真值为负时,补码=原码除符号位外每位取反,末尾+1 + +#### 4.反码表示法 + +负数的原码:符号位外每一位都取反 + +#### 5.三种机器数的总结 + ++ 最高位为符号位 ++ 对于整数,原码=补码=反码 ++ 对于负数,符号位为1,其数值部分: + + 原码取反+1→补码 + + 原码取反→反码 + +#### 6.移码表示法 + +补码难以判断其真值大小:补码的符号位取反 +$$ +[x]_移=2^n+x (x^n>x \geq -2^n) +$$ +最小真值的移码为全0 + +## 6.2 数的定点表示和浮点表示 + +### 6.2.1 定点表示 + +小数点按约定方式标出 + +### 6.2.2 浮点表示 + +浮点数的一般形式: +$$ +N=S \times r^j +$$ +S:尾数,j阶码,r基数(数值) + +计算机中r取2的n次方 + +当r=2时: +$$ +N=11.0101=0.110101 \times 2^{10} +$$ +——规格化数 + +计算机中:S存小数,可正可负,j存整数,可正可负 + ++ 浮点数的表示形式 + + 由j阶码和S尾数共同表示 + + 阶码包括阶符和阶码的数值部分,尾数同理,包含数符和尾数的数值部分 + + 阶码的位数反映浮点数的表示范围 + + 尾数的尾数反映浮点数的精度 + ++ 浮点数的表示范围 + + + 上溢:阶码>最大阶码 + + 下溢:阶码<最小阶码 按照**机器零**处理 + ++ 浮点数的规格化形式 + + + r=2 尾数最高位为1 + + r=4 尾数最高2位不全为0 + + r=8 尾数最高3位不全为0 + + r越大,浮点数表示范围越大,浮点数精度降低 + ++ 机器零: + + 阶码用移码,尾数用补码表示时,机器零才为:0,0000;0,00000 + +## 6.3 定点运算 + +### 6.3.1 移位运算 + ++ 移位的意义:与加减和配合实现乘除运算 + +左移:绝对值扩大 + +右移:绝对值缩小 + ++ 算数移位规则 + + 符号位不变 + + 正数移位:填补代码0 + + 负数移位: + + + 原码:添补0 + + 反码:添补1 + + 补码:右移添0,左移添1、 + ++ 算数移位和逻辑移位的区别:算术移位考虑符号位、补反码,逻辑移位不考虑 + +### 6.3.2 加减法运算 + +#### 1.补码加减运算 + +连同符号位一起加,符号位产生的进位自然丢掉 + +#### 2.溢出判断 + ++ 一位符号位判断溢出:参加运算的两个数符号位相同,其结果的符号与原操作数不同,即为溢出 ++ 两位符号位判断溢出:结果符号位不同即为溢出 + +### 6.3.3 乘法运算 + +#### 1.分析笔算乘法 + ++ 符号位单独处理 ++ 乘数的某一位决定是否加被乘数 ++ 4个位积一起相加——难以实现 ++ 乘积的尾数扩大一倍 + +#### 2.改进 + ++ 每一位乘法运算转化为加法运算后,右移一位 + +总结:乘法运算可以用加法和移位实现 + +#### 3.原码乘法 + +乘积的符号位单独处理 + +数值部分为绝对值相乘 + ++ 原码一位乘 ++ 原码两位乘 + +#### 4.补码乘法 + ++ 被乘数任意,乘数为正 + + 同原码乘,但加和移位按补码规则运算,乘积的符号自然形成 + ++ 被乘数任意,乘数为负 + + 乘数[y]补去掉符号位,其余同上 + + 最后加上[-x]补校正 + ++ Booth算法:初始时在乘数右边增加一个辅助位,根据当前位和辅助位两位判断: + + + 00/11,不加,移位 + + 01,+[x]补,移位 + + 10,+[-x]补,移位 + +### 6.3.4 除法运算 + ++ 符号位异或形成 ++ `abs(x)-abs(y)>0`上商1,反之上商0 ++ 余数左移一位,低位补0,减除数 ++ 1倍字长加法器 ++ 在寄存器最末尾上商 + +恢复余数法/加减交替法 + +## 6.4 浮点四则运算 + +### 6.4.1 浮点加减运算 + +对阶:求阶差,使小数点位置看齐(阶数小的向阶数大的看齐) + +尾数求和 + ++ 规格化数的判断: + + 原码:第一数位为1 + + 补码:符号位和第一数位不同 + +舍入: + +对阶右规的过程中尾数末尾可能丢失,需要考虑舍入 + ++ 0舍置1法 ++ 恒置1法 + +--- + +# 第七章 机器指令 + +## 7.1 机器指令 + +### 7.1.1 指令的一般格式 + +\[操作码字段\]\[地址码字段\] + +#### 1.操作码 反映机器做什么操作 + ++ 长度固定 ++ 长度可变 ++ 扩展操作码技术:操作码的位数随着地址数的减少而增加 + + 4位、8位操作码分别对应15条n地址、n-1地址指令 + +#### 2.地址码 + ++ 四地址 + + + 第一操作数地址 + + 第二操作数地址 + + 结果地址 + + 下一条指令地址 + + 4次访存 + ++ 三地址 + + + 使用PC代替下一条指令地址 + + 第一第二操作数地址及结果地址 + + 4次访存 + ++ 二地址 + + + 使用某一操作数地址代替结果地址,结果存于操作数 + + 结果存于ACC则仅需3次访存 + + 4次访存 + ++ 一地址 + + + 使用ACC代替某一操作数 + + 2次访存 + ++ 零地址 + + + 无地址码 + +### 7.1.2 指令字长 + +指令字长决定于 + ++ 操作码的长度 ++ 操作数地址的长度 ++ 操作数地址的个数 + +指令字长固定:指令字长=存储字长 + +指令字长可变:按字节的倍数变化 + +## 7.2 操作数类型和操作种类 + +### 7.2.1 操作数类型 + ++ 地址 无符号整数 ++ 数字 定点数、浮点数、十进制数 ++ 字符 ASCII ++ 逻辑数 逻辑运算 + +### 7.2.2 数据在存储值中的存放方式 + ++ 字地址为低字节地址 ++ 字地址为高字节地址 + +### 7.2.3 操作类型 + +#### 1.数据传送 + +从寄存器/存储器到存储器/寄存器 + +例如:MOVE/STORE/LOAD/PUSH/POP + +#### 2.算数逻辑操作 + +加减乘除与非... + +例:ADD SUB MUL DIV INC DEC CMP AND OR NOT XOR + +#### 3.移位操作 + +算术移位,逻辑移位,循环移位 + +#### 4.转移 + +无条件转移:JMP + +条件转移:JZ,JO,JC,SKP + +调用和返回(CALL,RETURN) + +陷阱与陷阱指令:意外事故的中断,一般由CPU自动产生并执行(隐指令) + +#### 5.输入输出 + +## 7.3 寻址方式 + +> **寻址**:确定本条指令的操作数地址,下一条欲执行指令的指令地址 + +寻址方式:指令寻址、数据寻址 + +### 7.3.1 指令寻址 + +顺序:PC+1→PC + +跳跃:由转移指令给出 + +### 7.3.2 数据寻址 + +| 操作码 | 寻址特征 | 形式地址A | +| ------ | -------- | --------- | + +> 形式地址:指令字中的地址 +> +> 有效地址:操作数的真实地址 + +约定指令字长=存储字长=机器字长 + +#### 1.立即寻址 + +形式地址就是操作数 + +#### 2.直接寻址 + +有效地址由形式地址直接给出,访问一次存储器 + +#### 3.隐含寻址 + +操作数地址隐含在操作码中,如ADD的一个操作数隐含在ACC中 + +#### 4.间接寻址 + +`EA=*A`,有效地址由形式地址间接提供,访存2次(一次间址)或多次(多次间址) + +可以扩大寻址范围,便于编制程序 + +#### 5.寄存器寻址 + +有效地址即为寄存器编号 + +#### 6.寄存器间接寻址 + +有效地址在寄存器中,便于编制循环程序 + +#### 7.基址寻址 + +EA=(BR)+A,BR为基址寄存器 + +也可采用通用寄存器作为基址寄存器,寄存器需要用户指定 + +BR不变,A可变 + +#### 8.变址寻址 + +EA=(IX)+A + +执行过程中A不变,IX可变 + +便于处理数组问题 + +#### 9.相对寻址 + +EA=(PC)+A + +A是相对于当前指令的位移量 + +广泛用于转移指令 + +#### 10.堆栈寻址 + +栈顶地址由SP指出 + +## 7.4 指令格式举例 + +### 7.4.1 设计指令格式时应考虑的各种因素 + ++ 指令系统的兼容性(向上兼容) ++ 其他因素 + + **操作类型** 包括指令个数以及操作的难易程度 + + **数据类型** 确定哪些数据类型可参与操作 + + **指令格式** 指令字长是否固定 + + **寻址方式** 指令寻址 + + **寄存器个数** 寄存器多少影响指令执行时间 + +### 7.4.2 指令格式举例 + ++ PDP-8 指令字长固定为12位 ++ PDD-11 指令字长有16位、32位、48位3种 ++ IBM 360 ++ INTEL 8086 + +## 7.4 RISC技术 + +### 7.4.1 RISC的产生和发展 + +RISC(Reduced Instuction Set Computer) + +CISC(Complex Instruction Set Computer) + +80-20规律:80%的语句仅仅使用20%的计算机指令 + +能否使用这20%组合成不常用的剩余指令 + +### 7.4.2 RISC的主要特征 + ++ 选用一些简单指令 ++ 长度固定、寻址方式少、指令格式种类少 ++ 只有LOAD/STORE访存 ++ CPU中有多个通用寄存器 ++ 采用流水技术,一个时钟周期内完成一条指令 ++ 采用组合逻辑实现控制器 ++ 采用优化的编译程序 + +### 7.4.3 CISC的主要特征 + ++ 复杂庞大 ++ 长度不固定,格式种类多 ++ 访存指令不受限制 ++ CPU中有专用寄存器 ++ 大多数指令需要多个时钟周期执行完毕 ++ 采用微程序控制器 ++ 难以用优化编译生成高效代码 + +### 7.4.4 RISC和CISC的比较 + ++ RISC更能充分利用VLSI芯片的面积 ++ RISC更能提高计算机速度,便于实现指令流水 ++ RISC便于设计,降低成本提高可靠性 ++ RISC有利于编译程序优化 ++ RISC**不易**实现指令程序兼容 + +--- + +# 第八章 CPU的结构和功能 + +## 8.1 CPU的结构 + +### 8.1.1 CPU的功能 + ++ 控制器 + + 取指令 + + 分析指令 + + 执行指令,发出操作命令 + + 控制程序输入以及结构的输出 + + 总线管理 + + 处理异常情况和特殊请求 ++ 运算器 + + 实现算数运算和逻辑运算 + +### 8.1.2 CPU结构框图 + +指令控制 PC,IR + +操作控制、时间控制 CU,时序电路 + +数据加工 ALU,寄存器 + +处理中断 中断系统 + +![CPU结构框图](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_33.png) + +### 8.1.3 CPU的寄存器 + ++ 用户可见寄存器 + + + 通用寄存器 + + 数据寄存器 + + 地址寄存器 + + 条件码寄存器 + ++ 控制和状态寄存器 + + + 控制寄存器 + + PC MAR M MDR IR + + 控制CPU操作,其中MAR,MDR,IR用户不可见,PC用户可见 + + + 状态寄存器 + +### 8.1.4 控制单元CU和中断系统 + ++ CU 产生全部指令的微操作命令序列 + + 组合逻辑设计 + + 微程序设计 ++ 中断系统 + +### 8.1.5 ALU + +参见第六章 + +## 8.2 指令周期 + +### 8.2.1 指令周期的基本概念 + +> **指令周期**:取出并执行一条指令所需的全部时间 + +完成一条指令: + ++ 取指、分析:取指周期 ++ 执行:执行周期 + +每条指令的指令周期不同 + +指令周期还可以加入:间址周期(间接寻址)、终端周期 + ++ CPU工作周期的标志 + + 四种性质: + + + 取指令 取指周期 + + 取地址 间址周期 + + 取操作数 执行周期 + + 存程序断点 中断周期 + +### 8.2.2 指令周期的数据流 + ++ 取指周期 + + ![](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_34.png) + ++ 间址周期 + + ![](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_35.png) + ++ 执行周期——不同指令数据流不同 + ++ 中断周期 + + ![](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_36.png) + +## 8.3 指令流水 + +### 8.3.1 如何提高机器速度 + ++ 提高访存速度 + + 高速芯片 Cache 多体并行 + ++ 提高I/O和主机之间的传送速度 + + 中断-DMA-通道-I/O处理机-多总线 + ++ 提高运算器速度 + ++ 提高整机处理能力 + + + 高速器件 + + 改进系统结构,开发系统的并行性 + +### 8.3.2 系统的并行性 + ++ 并行的概念 + + > **并发**:两个或两个以上的事件在同一时间段发生 + > + > **同时**:两个或两个以上的事件同一时刻发生 + ++ 并行性的等级 + + + 过程级 粗粒度 软件实现 + + 指令级 细粒度 硬件实现 + +### 8.3.3 指令流水原理 + +#### 1.指令的串行执行 + +取指令1-执行指令1-取指令2-... + +总有一个部件空闲 + +#### 2.指令的二级流水 + +| 取指令1 | 执行指令1 | | | +| ------- | --------- | --------- | --------- | +| | 取指令2 | 执行指令2 | | +| | | 取指令3 | 执行指令3 | + +取指和执行上时间重叠,指令周期减半 + +#### 3.影响指令流水效率加倍的因素 + ++ 指令时间>取指事件 ++ 条件转移指令对流水有影响:必须等待上条指令执行完成才能确定下一条指令 + +#### 4.指令的六级流水 + +![db_01.png (1806×755)](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/co_37.png) + +### 8.3.4 影响指令流水线性能的因素 + ++ 结构相关:不同指令争用同一功能产生资源冲突 + + 解决方法 + + + 停顿 + + 数据存储器和指令存储器分开 + + 指令预取技术 + ++ 数据相关:不同指令重叠操作,可能改变操作数的读写访问顺序 + + 解决方法 + + + 后推法 + + 采用旁路技术 + ++ 控制相关:由转移指令引起 + +### 8.3.5 流水线性能 + ++ 吞吐率:单位时间内流水线完成指令或输出结果的数量 + + 最大吞吐率:1/每段流水线时间 + + 实际吞吐率(连续处理n条指令):n/(流水线段数\*流水线时间+(n-1)\*流水线时间) + ++ 加速比:流水线的速度与等功能的非流水线速度之比 + + 设m段流水线上完成n条指令:nm/(m+n-1) + ++ 效率:流水线中各功能段的利用率 + 由于流水线有 建立时间 和 排空时间 + 因此各功能段的 设备不可能 一直 处于 工作 状态 + + 效率=流水线各段处于工作时间的时空区/流水线总的时空区=mnt/m(m+n-1)t + +### 8.3.6 流水线的多发技术 + ++ 超标量技术:并发多条独立指令 ++ 超流水线技术:一个时钟周期内再分段 ++ 超长指令字技术:编译程序挖掘潜在并行性,多条指令并行 + +### 8.3.7 流水线结构 + ++ 指令流水线结构 + + 完成一条指令分7段:取指令、指令译码、地址形成、取操作数、操作执行、回写结果、修改指令指针 + + 理想情况下7级流水的速度是不使用的7倍 ++ 运算流水线 + + 浮点加减运算分为对阶、尾数求和、规格化三段 + + 分段原则:每段操作时间尽量一致 + +## 8.4 中断系统 + +### 8.4.1 概述 + ++ 引起中断的各种因素 + + 人为设置的中断 + + 程序型事故 + + 硬件故障 + + I/O设备 + + 外部设备(键盘中断) ++ 中断系统需解决的问题 + + 中断源如何向CPU提出请求 + + 同时提出请求如何处理 + + CPU什么条件下,WHEN,HOW,响应中断 + + 如何保护现场 + + 如何寻找入口地址 + + 如何恢复现场,返回 + + 处理中断中如何处理新的中断 + +### 8.4.2 中断请求标记和中断判优逻辑 + +#### 1.中断请求标记INTR + +一个请球源一个INTR + +多个INTR组成中断请求标记寄存器 + ++ INTR可以分散在中断源的接口电路中 ++ 也可以集中在CPU中断系统内 + +#### 2.中断判优逻辑 + ++ 硬件实现:排队器 ++ 软件实现:程序查询 + +### 8.4.3 中断服务程序入口的寻找 + ++ 硬件向量法 ++ 软件查询法 + +### 8.4.4 中断响应 + +#### 1.中断响应的条件 + +允许中断触发器EINT=1 + +#### 2.响应中断的时间 + +指令执行周期结束时刻CPU发送查询信号 + +#### 3.中断隐指令 + ++ 保护程序断点 ++ 寻找服务程序入口地址 ++ 硬件关中断 + +### 8.4.5 保护现场和恢复现场 + ++ 保护现场 + + 断点:中断隐指令完成 + + 寄存器内容:中断服务程序完成 ++ 恢复现场:中断服务程序完成 + +### 8.4.6 中断屏蔽技术 + +> **多重中断**:如果CPU在执行某一中断服务程序过程中,又遇到了新的更高级的中断请求,CPU暂停原中断的处理,而转去处理新的中断,待处理完毕后,再返回继续处理原来的中断,这种中断称为多重中断,也称中断嵌套。 + ++ 实现多重中断的条件 + + 提前设置开中断指令 + + 优先级别高的中断有权中断优先级别低的中断源 + ++ 屏蔽技术 + + 屏蔽触发器MASK + + 屏蔽字 + + 屏蔽技术可改变优先处理等级 + + 可以人为地屏蔽某个中断源地请求,便于程序控制 diff --git a/docs/Database.md b/docs/Database.md new file mode 100644 index 0000000..7064767 --- /dev/null +++ b/docs/Database.md @@ -0,0 +1,1166 @@ +*written by PeterAlbus,Copyright © 2021 - SHOU 1951123 Hong Wu* + +# 第一章 数据库概论 + +## 1.2 数据库的由来和发展 + +### 1.2.2 文件系统阶段 + +文件系统的三个缺陷: + ++ 数据冗余 ++ 数据不一致 ++ 数据联系弱 + +### 1.2.3数据库阶段 + +数据库阶段的五个特点: + ++ 采用数据模型表示复杂的数据结构 ++ 有较高的数据独立性 ++ 数据库系统为用户提供了方便的接口 ++ 提供如下4个方面的数据控制功能 + + 数据库的恢复 + + 数据库的并发控制 + + 数据的完整性 + + 数据安全性 ++ 增加了系统的灵活性 + +![数据库系统的结构](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/db_01.png) + +> 数据库(Database, DB)。DB是长期储存在计算机内,有组织的,统一管理的**相关数据的集合**。DB能为各种用户共享,具有较小冗余度、数据间联系紧密而又有较高的数据独立性等特点。 + +> 数据库管理系统(Database Management System, DBMS)。DBMS是位于用户与操作系统(OS)之间的一层**数据管理软件**。它为用户或应用程序提供访问DB的方法,包括DB的建立,查询,更新以及各种数据控制。 + +DBMS可分为: + ++ 层次型 ++ 网状型 ++ 关系型 ++ 面向对象型 ++ etc. + +> 数据库系统(Database System, DBS)。DBS是实现有组织地,动态地存储大量关联数据,方便多用户访问的计算机硬件、软件和数据资源组成的系统,即它是**采用数据库技术的计算机系统**。 + +## 1.3 数据描述 + +概念设计->逻辑设计->物理设计 + +### 1.3.4 数据联系的描述 + +> 联系(Relationship)是实体间的相互关系,与一个联系有关的实体集个数,称为联系的元数。 + ++ 一元联系 ++ 二元联系 + + 一对一联系 1:1 + + 一对多联系 1:N + + 多对多联系 M:N ++ 三元联系等 + +**例1.2** 给定一定的联系及其类型(一对一/一对多/多对多),用单箭头指向“一端”的实体集,用双箭头指向"多端"的实体集。 + +**例1.3** 三元联系和一元联系类型举例: + +如零件可以由若干个子零件组成,也可是其他零件的子零件,因此自身对自身是M:N + +![一元联系、三元联系举例](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/db_02.png) + +## 1.4 数据抽象的级别 + +### 1.4.1 数据抽象的过程 + +现实世界的信息->数据库存储:逐步抽象的过程 + +> 表达用户需求观点的数据全局逻辑的模型称为“概念模型”,表达计算机实现观点的DB全局逻辑结构的模型称为“逻辑模型”,表达用户使用观点的DB局部逻辑模型称为“外部模型”,表达DB物理结构的模型称为"内部模型"。 + +![4种模型之间的相互关系](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/db_03.png) + +### 1.4.2 概念模型 + +概念模型的抽象级别最高,特点如下所述: + ++ 概念模型表达了数据的整体逻辑结构,是系统用户对整个应用项目涉及的数据的全面描述。 ++ 概念模型是从用户需求的观点出发,对数据建模。 ++ 概念模型独立于硬件(硬件设备)和软件(实现时的DBMS软件)。硬件/软件的变化不会影响DB的概念模型设计。 ++ 概念模型是数据库设计人员与用户之间进行交流的工具。 + +现在采用的概念模型主要是实体联系(ER, Entity Relationship)模型,ER模型主要由ER图来表示。 + +> ER图有3个基本成分 +> +> + 矩形框:用于表示实体类型(考虑问题的对象,如学生,课程)。 +> + 菱形框:用于表示联系类型(实体间联系,如选课)。 +> + 椭圆形框:用于表示实体类型和联系类型的属性。 +> +> 相应的命名均记入各种框中,实体与属性,联系与属性之间用直线相连,联系类型两端用直线连接涉及的实体类型,并在直线段标注联系的类型。 + +### 1.4.3 逻辑模型 + +逻辑模型具有以下特点 + ++ 逻辑模型表达了DB的整体逻辑结构。 ++ 是从数据库实现的观点出发对数据建模 ++ 独立于硬件,但依赖于软件(DBMS) ++ 逻辑模型是数据库设计人员与应用程序员之间进行交互的工具。 + +主要有层次、网状、关系和对象模型共四种。 + +#### 1.层次模型 + +#### 2.网状模型 + +#### 3.关系模型 + +关系模型的特征主要是用二位表格表达实体集。关系模型是由若干个关系模式(Relational Schema)组成的集合。关系模式的实例称为关系。每个关系实际上是一张二维表格(Table)。 + +> TEACHER模式 `(T#,TNAME,TITLE) ` +> +> COURSE模式 `(C#,CNAME,T#)` +> +> STUDENT模式 `(S#,SNAME,AGE,SEX)` +> +> SC模式`(S#,C#,SCORE)` + +如上为关系模式的例子,关系模式的实例(关系)将会是一张表格,如下所示,是TEACHER模式的实例: + +| T# | TNAME | TITLE | +| ---- | ----- | ------ | +| T2 | SHI | 教授 | +| T3 | LI | 副教授 | +| T1 | DAI | 讲师 | +| T4 | GU | 讲师 | + +#### 4.对象模型 + +### 1.4.4 外部模型 + +实际使用时,可以为不同的业务单位设计不同的外部模型。 + +**例** 存在关系模型,由如下四个关系模式组成 + +> TEACHER模式 `(T#,TNAME,TITLE) ` +> +> COURSE模式 `(C#,CNAME,T#)` +> +> STUDENT模式 `(S#,SNAME,AGE,SEX)` +> +> SC模式`(S#,C#,SCORE)` + +在这个基础上,可以为学生应用子系统设计一个外部模型外部模型中的模式称为“视图”,这个视图如下: + +> 学生视图 `STUDENT_VIEW(S#,SNAME,C#,CNAME,SCORE,T#,TNAME)` + +视图只是一个定义,视图中的数据可以从逻辑模型的数据库中得到。 + +外部模型具有如下特点 + ++ 外部模型是逻辑模型的一个逻辑子集 ++ 外部模型独立于硬件,依赖于软件 ++ 外部模型反映了用户使用数据库的观点 + +### 1.4.5 内部模型 + +内部模型又称为物理模型,是数据库最低层的抽象,它描述数据在硬盘或磁带上的存储方式,存取设备和存取方法。内部模型与硬件和软件紧密相连。 + +### 1.4.6 三层模式与两级映像 + +#### 1.三层模式体系结构 + +在用户(或应用程序)到数据库之间,DB的数据结构有3个层次,外部模型,逻辑模型和内部模型。这3个层次要用DB的数据定义语言(Data Definition Language,DDL)定义,定义后的内容,称为模式(Schema)。 + +> 从用户(或应用程序)到数据库之间,DB的数据结构描述有3个层次: +> +> + 外模式 用户与数据库系统的结构,是用户用到的那部分数据的描述。 +> + 逻辑模式 是数据库中全部数据的整体逻辑结构的描述。 +> + 内模式 数据库在物理存储方面的描述 + +#### 2.两级映像 + +> 三层模式之间存在着两级映像: +> +> + 外模式/逻辑模式映像存在于外模式和逻辑模式之间,用于定义外模式和逻辑模式间的对应性,这个映像一般是放在外模式中描述的 +> + 逻辑模式/内模式映像存在于逻辑模式和内模式之间,这个映像一般是放在内模式中描述的 + +### 1.4.7 高度的数据独立性 + +> 数据独立性(Data Independence)是指应用程序和数据库的数据结构之间相互独立,不受影响,在修改数据结构时,尽可能不修改应用程序,则称系统达到了数据独立性目标。 + ++ 物理数据独立性 + + 如果数据库的内模式要修改,只要对逻辑模型/内模式映像作相应的修改,可以使逻辑模式经可能保持不变,这时,称数据库达到了物理数据独立性。 + ++ 逻辑数据独立性 + + 如果数据库的逻辑模式要修改,只要对外模式/逻辑模式映像做相应的修改,可以使外模式和应用程序京可能保持不变,这时,称数据库达到了逻辑数据独立性。 + +## 1.5 数据库管理系统 + +### 1.5.1 DBMS的工作模式 + +数据库管理系统(DBMS)是指数据库系统中对数据进行管理的软件系统。 + +![用户访问数据库的过程](https://file.peteralbus.com/assets/blog/imgs/blogimg/private/db_04.png) + +### 1.5.2 DBMS的主要功能 + +1. 数据库的定义功能 +2. 数据库的操纵功能 +3. 数据库的保护功能 +4. 数据库的维护功能 +5. 数据字典 + +-------------------------- + +# 第二章 关系模型和关系运算理论 + +## 2.1 关系模型的基本概念 + +### 2.1.1 基本术语 + +> 用二维表格表示实体集,用关键码表示实体之间联系的数据模型称为关系模型(Relation Model) + +在关系模型中: + +字段称为**属性**,字段的值称为**属性值**,为列(Column) + +记录类型称为**关系模式** + +记录称为**元组**(Tuple), 为行(Row) + +元组的集合称为**关系**(Relation)或实例(Instance) + +属性的个数称为**元数**,元组个数称为**基数** + +关键码(Key,键)由一个或多个属性组成,在实际使用中,有以下几种键: + ++ 超键(Super Key),在关系中能唯一标识元组的属性或属性集称为关系模式的超键。 ++ 候选键(Candidate Key),不含有多余属性的超键称为候选键,候选键中再删除属性便不是键。 ++ 主键(Primary Key),用户选作元组表示的候选键称为主键。 ++ 外键(Foreign Key),如果模式R中属性K是其他模式的主键,那么K在模式R中称为外键。 + +### 2.1.2 关系的定义和性质 + +> 关系是一个属性数目相同的元组的集合 + +严格地讲,关系是一种规范化了的二维表格,在关系模型中,对关系作了下列规范性限制: + ++ 关系中每个属性都是不可分解的 ++ 关系中不允许出现重复元组 ++ 由于关系是一个集合,因此不考虑元组间的顺序,即没有行序 ++ 元组中的属性在理论上也是无序的,但使用时按习惯考虑列的顺序 + +### 2.1.3 关系的3类完整性规则 + +#### 1. 实体完整性规则 + +在组成主键的属性上不能有空值 + +#### 2.参照完整性规则 + +> 如果属性集K是关系模式R1的主键,K也是关系模式R2的外键,那么在R2的关系中,K的取值只有两种可能:或者为空值,或者等于R1关系中的某个主键值。 + +实质:不允许引用不存在的实体 + +#### 3.用户定义的完整性规则 + +在建立关系模式时,数据可以针对具体的数据约束,设置完整性规则,由系统来检验实施。 + +## 2.2 关系代数 + +### 2.2.1 关系代数的5个基本操作 + +关系定义为属性个数相同的元组的集合,因此集合代数中的操作可以引入到关系代数中。 + +#### 1.并(Union) + +R和S具有相同的关系模式,R和S的并是属于R或属于S的元组构成的集合。记为: +$$ +R \cup S\equiv\lbrace t \mid t \in R \wedge t\in S \rbrace +$$ + +#### 2.差(Difference) + +R和S具有相同的关系模式,R和S的差是属于R但不属于S的元组构成的集合。记为: +$$ +R \cap S\equiv\lbrace t \mid t \in R \wedge t \notin S \rbrace +$$ + +#### 3.笛卡儿积(Cartesian Product) + +设关系R和关系S的元数分别为r和s,定义R和S的笛卡尔积是一个(r+s)元的元组集合,每个元组的前r个分量来自R的一个元组,后s个分量来自S的一个元组,记为: +$$ +R \times S\equiv\lbrace t \mid t= \langle t^r,t^s \rangle \wedge t^r \in R \wedge t^s \in S\rbrace +$$ + +#### 4.投影(Projection) + +对一个关系进行垂直分割,按顺序选出某些列。 +$$ +\pi_{i_1,\ldots,i_m}(R)\equiv\lbrace t \mid t = \langle t_{i_1},\ldots,t_{i_m} \rangle \wedge \langle t_1,\ldots,t_k \rangle \in R \rbrace +$$ +操作符$\pi$的下标处也可以用属性名表示。 + +#### 5.选择(Selection) + +选择操作时根据某些条件对关系做水平分割,即选取符合条件的元组。 + +选取的条件F有两种成分: + ++ 运算对象:常数,元组分量(属性名/列的序号) ++ 运算符:算术比较运算符、逻辑运算符 + +形式定义如下: +$$ +\sigma_F(R) \equiv \lbrace t \mid t \in R \wedge F(t)=true \rbrace +$$ +$\sigma_F(R)$表示从R中挑选满足公式F为真的元组所构成的关系。 + +### 2.2.2 关系代数的4个组合操作 + +组合操作可由前面5个基本操作推出。 + +#### 1.交(Intersection) + +关系R和关系S的交是属于R又属于S的元组构成的集合,形式定义如下(R和S的元数相同): +$$ +R \cap S \equiv \lbrace t \mid t \in S \wedge t \in S \rbrace +$$ + +#### 2.连接(Join) + +连接是从关系R和S的笛卡尔积中选取属性值满足某一$\Theta$操作的元组,形式定义如下: +$$ +R\Join_{i \theta j} S \equiv \lbrace t \mid t = \langle t^t,t^s \rangle \wedge t^s \in S \wedge t^r_i \theta t^s_j \rbrace +$$ +显然,连接操作由笛卡尔积和选择操作组合而成。 + +如果$\theta$是等号,该连接操作被称为等值连接。 + +#### 3.自然连接(Natural Join) + +两个连接关系R和S的自然连接操作用$R\Join S$表示,计算过程如下: + +1. 计算$R \times S$ +2. 设R和S的公共属性是$A_1, \ldots ,A_K$,挑选$R \times S$中满足$R.A_1=S.A_1, \ldots ,R.A_K=S.A_K$的元组。 +3. 去掉$S.A_1, \ldots ,S.A_K$这些列 + +#### 4.除法(Division) + +概念定义较为抽象,难以理解,用自然语言简要说明: + +R/S的流程: + ++ 从S中选择出R和S的重复属性:Y,从R中去除R和S的重复属性,去除后的关系称为X,即X为不重复属性 ++ 对X中的每个元组,在R中找出对应的Y的象集,即找出所有X的元组在R中对应的属性和Y一样的Y元组。 ++ 若X中的每个元组在R中对应的Y的元组包含了所有Y,则X在R/S的最终结果中。 + +## 2.4 关系代数表达式的优化 + +### 2.4.3 启发式优化算法 + +启发式规则: + ++ 尽可能早地执行选择操作 ++ 尽可能早的执行投影操作 ++ 避免直接做笛卡儿积,把笛卡儿积之前和之后地一连串选择和投影操作合并起来一起做 + +---------------------------------------------- + +# 第三章 关系数据库语言SQL + +## 3.2 SQL的数据定义 + +### 3.2.1 SQL的模式的创建和撤销 + +创建模式`CREATE`和撤销模式`DROP`: + +```sql +CREATE SCHEMA <模式名> +DROP SCHEMA <模式名> [CASCADE|RESTRICT] +``` + +`CASCADE`:级联式,执行DROP语句时把SQL模式及其下属的基本表、视图、索引等元素全部撤销。 + +`RESTRICT`:约束式,没有任何下属元素才能执行,否则拒绝执行 + +SQL模式一词较为偏向学术,许多DBMS中会将模式称为数据库,采用`CREATE DATABASE`语句。 + +### 3.2.2 基本数据类型 + ++ 数值型 + + INTEGER/INT 整数,长度4B + + SMALLINT 短整数,长度2B + + REAL 浮点数 + + DOUBLE PRECISION 双精度浮点数 + + FLOAT(n) 精度至少为n个数字的浮点数 + + NUMERIC(p,d)/DECIMAL(p,d)/DEC(p,d) 定点数,p位整数,d位小数 ++ 字符串型 + + CHAR(n) 长度为n的定长字符串(不足长度补空格) + + VARCHAR(n) 最大长度为n的变长字符串 ++ 位串型 + + BIT(n) 长度为n 的二进制位串 + + BIT VARYING(n) 最大长度为n的变长二进制位串 ++ 时间型 + + DATE 日期,YYYY-MM-DD + + TIME 时间,HH:MM:SS + +### 3.2.3 基本表的创建、修改和撤销 + +#### 1.基本表的创建 + +```sql +CREATE TABLE <基本表名> + ( + <列名类型>, + ... + <完整性约束>, + ... + ) +``` + +每个列的类型可以是基本数据类型,也可以是用户事先定义的域名。 + +完整性约束包含主键子句(`PRIMARY KEY`)、外键子句(`FOREIGN KEY`)和检查子句(`CHECK`) + +例: + +```sql +CREATE TABLE T +( + T# CHAR(4) NOT NULL, + TNAME CHAR(8) NOT NULL, + TITLE CHAR(10), + PRIMARY KEY(T#); +); +``` + +#### 2.基本表的结构的修改 + ++ 增加新的列用"`ALTER ... ADD ...`"语句 ++ 删除原有的列用"`ALTER ... DROP ...`"语句 ++ 修改原有列的类型、宽度用“`ALTER ... MODIFY ...`”语句 + +```sql +ALTER TABLE <基本表名> ADD <列名> <类型> +ALTER TABLE S ADD ADDRESS VARCHAR(30); + +ALTER TABLE <基本表名> DROP <列名> [CASCADE|RESTRICT] +ALTER TABLE S DROP AGE CASCADE; + +ALTER TABLE <基本表名> MODIFY <列名><类型> +ALTER TABLE S MODIFY S# CHAR(6); +``` + +#### 3.基本表的撤销 + +```sql +DROP TABLE <基本表名> [CASCADE|RESTRICT] +DROP TABLE S RESTRICT; +``` + +## 3.3 SQL的数据查询 + +### 3.3.1 SELECT查询语句的基本结构 + +#### 1.SELECT 句型 + +关系代数中最常用的式子为下列表达式: +$$ +\pi_{A_1, \ldots ,A_n} (\sigma_F(R_1 \times \ldots \times R_m)) +$$ +根据该表达式,SQL设计了SELECT-FROM-WHERE 句型 + +```sql +SELECT A,B,... +FROM R,S,... +WHERE F +``` + +该句型由关系代数表达式演变而来。WHERE子句中的条件表达式更加灵活,可使用下列运算符: + ++ 算数比较运算符 ++ 逻辑运算符:AND,OR,NOT ++ 集合成员资格运算符:IN,NOT IN ++ 谓词:EXISTS,ALL,SOME,UNIQUE ++ 聚合函数:AVG,MIN,MAX,SUM ++ 运算对象可以是另一个SELECT语句 + +SELECT语句能表达所有的关系代数表达式 + +#### 2.SELECT语句的使用技术 + +SELECT语句使用时的三种写法:连接查询、嵌套查询、带存在量词的嵌套查询。 + +**例**:对于数据库以下四个关系 + +> T `(T#,TNAME,TITLE) ` +> +> C `(C#,CNAME,T#)` +> +> S `(S#,SNAME,AGE,SEX)` +> +> SC`(S#,C#,SCORE)` + +查询语句:检索学习课程号为C2课程的学生学号与姓名 + +```sql +#连接查询 +SELECT S,`S#`,SNAME +FROM S,SC +WHERE S.S#=SC.S# AND `C#`='C2'; +#嵌套查询 +SELECT `S#`,SNAME +FROM S +WHERE `S#` IN(SELECT `S#` + FROM SC + WHERE `C#`='C2'); +#使用存在量词的嵌套查询 +SELECT `S#`,SNAME +FROM S +WHERE EXISTS(SELECT C# + FROM SC + WHERE `S#`=SC.S#); +``` + +### 3.3.2 SELECT语句的完整结构 + +```sql +SELECT <目标表的列名或列表达式序列> #列表达式序列指对于一个单列求聚合值的表达式,也允许常用算数表达式 +FROM <基本表名和(或)视图序列> +[WHERE <行条件表达式>] +[GROUP BY <列名序列> + [HAVING <组条件表达式>]] +[ORDER BY <列名[ASC|DESC]>,...] +``` + +执行过程: + +1. 读取FROM子句中基本表和视图的数据,执行笛卡尔积操作 +2. 选取满足WHERE子句中给出的条件表达式的元组 +3. 按GROUP子句中指定的列的值分组,同时提取满足HAVING子句中条件表达式的那些组 +4. 按SELECT子句中给出的列名或列表达式求职输出 +5. ORDER子句对输出目标表进行排序,附加说明按ASC升序排列,或按DESC降序排列 + +### 3.3.3 数据查询中的限制与规定 + +#### 1.SELECT子句规定 + +`SELECT [ALL|DISTINCT] ....` + +DISTINCT用于将重复的行从结果中去除。 + +默认为ALL,保留重复行。 + +#### 2.列和基本表的改名操作 + +可在SELECT子句中用`<旧名> AS <新名>`改名 + +#### 3.集合的交、并、差操作 + +当两个子查询的结果结构完全一致时,可让两个子查询执行交、并、差操作。 + +运算符为`UNION`,`INTERSECT`,`EXCEPT` + +### 3.3.4 条件表达式中的比较操作 + +#### 1.算术比较操作 + +条件表达式中可用算术比较运算符:>、<、>=、<=、=、!=,也可用`BETWEEN ... AND ...` + +#### 2.字符串匹配操作 + +字符串匹配操作符是`LIKE`,表达式中可使用两个通配符: + ++ 百分号(%):与0个或多个任意字符匹配 ++ 下划线(_):与单个字符匹配 + +需要时也可使用`NOT LIKE` + +#### 3.空值比较操作 + +`IS NULL` + +#### 4.集合成员资格的比较 + +```sql +<元组> [not] in (<集合>) +SELECT SNo +FROM S +WHERE SNo NOT in (SELECT SNo + FROM SC + WHERE CNo IN ('C2','C4')); +``` + +#### 5.集合成员的算数比较 + +``` +<元组> <运算符> ALL|SOME|ANY (<集合>) +``` + +`in` 可用`=SOME`代替 + +#### 6.集合空否的测试 + +```sql +[NOT] EXISTS(<集合>) +``` + +结果为true/false + +#### 7.集合是否存在重复元组的测试 + +```sql +[NOT] UNIQUE(<集合>) +``` + +## 3.4 SQL数据更新 + +## 3.5 视图 + +### 3.5.1 视图的创建和撤销 + +```sql +CREATE VIEW <视图名>(<列名序列>) + AS