深入理解操作系统(10)第四章:处理器体系结构(2)Y86-64的顺序实现(包括:SEQ/指令的各阶段操作:取指,解码,执行,访存,回写,更新PC/序列指令/硬件结构/时序/阶段的实现/SEQ+)

  • 1. Y86-64的顺序实现
    • 1.1 将处理组织成阶段
      • 1.1.1 阶段序列
      • 1.1.2 一条指令执行的6个阶段
      • 1.1.3 一条指令要进行很多处理(远不止上面6个阶段)
      • 1.1.4 Y86指令序列指令
      • 1.1.5 subl 指令执行
      • 1.1.6 rmmovl 和 mrmovl 处理
      • 1.1.7 rmmovl 指令的执行
      • 1.1.8 pushl 和 popl 指令
      • 1.1.9 pushl 指令的执行
      • 1.1.10 跳转jxx、cat和ret
      • 1.1.11 je跳转指令的执行
      • 1.1.12 ret 指令的执行
    • 1.2 SEQ硬件结构
      • 1.2.1 SEQ抽象视图,顺序执行结构
      • 1.2.2 硬件单元与各处理阶段关联
      • 1.2.3 SEQ硬件结构,顺序执行
      • 1.2.4 硬件作图惯例
      • 1.2.5 标识顺序实现中的不同计算步骤
    • 1.3 SEQ的时序
      • 1.3.1 两种存储器设备
      • 1.3.2 组合逻辑
      • 1.3.3 四个硬件单元需要定序
      • 1.3.4 例子说明
    • 1.4 SEQ阶段的实现
      • 1.4.1 HCL描述
      • 1.4.2 取指阶段
      • 1.4.3 解码和写回阶段
      • 1.4.4 执行阶段
      • 1.4.5 访存阶段
      • 1.4.6 跟新PC阶段
    • 1.5 SEQ小结
    • 1.6 SEQ+重新安排计算阶段
      • 1.6.1 SEQ+
      • 1.6.2 SEQ 和 SEQ+ PC的比较
      • 1.6.3 电路重定时
      • 1.6.4 SEQ+中的PC在哪里?

1. Y86-64的顺序实现

现在我们已经有了实现Y86处理器所需要的部件。首先,我们讲一个称为SEQ的处理器。

SEQ(取的是“sequentia”处理器的意思)的处理器。

每个时钟周期上,SEQ执行用来处理一条完整指令所需的所有步骤。
不过这需要一个很长的时钟周期时间,因此时钟周期频率会低到不可接受。
我们开发SEQ的目标就是提供实现我们最终目的的第一步,我们的最终目的是实现一个高效的、流水线化的处理器。

时钟周期也称为振荡周期,定义为时钟频率的倒数。
通常频率是100(1秒钟震荡100次),那么他的精度度或者说时钟周期就是10ms。

1.1 将处理组织成阶段

1.1.1 阶段序列

通常,处理一条指令包括很多操作。

我们将它们组织成某个特殊的阶段序列,使得即使指令的动作差异很大,但所有的指令都遵循统一的序列。

每一步的具体处理取决于正在执行的指令。

创建这么一个框架使我们能够设计一个能充分利用硬件的处理器。

1.1.2 一条指令执行的6个阶段

下面是关于各个阶段以及各阶段内执行操作的简略描述:

1. 取指(fetch):取指阶段从存储器读入指令,地址为程序计数器(PC)的值。从指令中抽取出指令指示符字节的两个四位部分,称为 icode(指令代码)和ifun(指令功能)。它可能取出一个寄存器指示符字节,指明一个或两个寄存器操作数指示符rA和rB。它还可能取出个四字节常数字vaC。它按顺序方式计算当前指令的下一条指令的地址valP。也就是说valP等于PC的值加上已取出指令的长度2. 解码(decode): 解码阶段从寄存器文件读入最多两个操作数,得到值valA和或valB。通常,它读入指令rA和rB字段指明的寄存器,不过有些指令是读寄存器%esp的3. 执行(execute):在执行阶段,算术/逻辑单元(ALU)要么执行指令指明的操作(根据ifun的值),计算存储器引用的有效地址,要么增加或减少栈指针。我们称得到的值为valE。在此,也可能设置条件码。对一条跳转指令来说,这个阶段会检验条件码和(ifun给出的)分支条件,看是不是应该选择分支。4. 访存(memory):访存阶段可以将数据写入存储器,或者从存储器读出数据。读出的值为vaM5. 写回(write back): 写回阶段最多可以写两个结果到寄存器文件。6. 更新PC(PC update): 将PC设置成下一条指令的地址

处理器无限制地循环执行这些阶段,只有在遇到halt指令或一些错误情况时,才会停下来。
我们处理的错误情况包括非法存储器地址(程序地址或数据地址),以及非法指令。

1.1.3 一条指令要进行很多处理(远不止上面6个阶段)

从前面的讲述可以看出,执行一条指令是需要进行很多处理的。
不仅要执行指令所表明的操作还要计算地址、更新栈指针,以及确定下一条指令的地址。
幸好每条指令的整个流程都比较相似。因为我们想使硬件数量尽可能的少,并且最终将把它映射到一个二维的集成电路芯片的表面,

一个非常简单而一致的结构是非常重要的。
降低复杂度的一种方法是让不同的指令共享尽量多的硬件。

例如,我们的每个处理器设计都只含有一个算术/逻辑单元,根据所执行的指令类型的不同,它的使用方式也不同。在硬件上复制逻辑块的成本比软件中有重复代码的成本大得多,而且在硬件系统中处理许多特殊情况和特性要比用软件来处理困难得多。

1.1.4 Y86指令序列指令

我们面临的一个挑战是将每条不同指令所需要的计算放入到上述那个通用框架中。
我们会使用图4.15中所示的代码来描述不同Y86指令的处理。
图4.15

后面的所有指令例子操作都是基于此,所以请认真看!!!

图4.16~图4.19中的表描述了不同Y86指令在各个阶段是怎样处理的。
要好好研究一下这些表,表中的这种格式很容易映射到硬件。

这些表中的每一行都描述了一个信号或存储状态的分配。

计算一个值并将结果放入寄存器中。rrmovl irmovl 指令例子。
图4.16

注释:符号 icode: ifun  icode(指令代码)和ifun(指令功能)rA rB表明寄存器指示符字节的两个组成部分符号[M1x]表示访问(读或者写)存储器位置M处的一个字节,而[M4x]表示访问四个字

1.1.5 subl 指令执行

作为一个例子,让我们来看看一条subl指令的处理过程,这条指令是图4.l5所示目标代码的第3行中的sub指令。

执行: 0x00c:6123    subl %edx %ebx  //9 21
结果: %ebx = %ebx - %edx = 21 - 9 = 12

我们可以看到前面两条指令分别将寄存器%edx和%ebx初始化成9和21。
还能看到指令是位于地址0x00c,有两个字节,值分别为0x61和0x23。
这条指令的处理如下图所示,左边列出了处理一个OPl指令的通用的规则而右边列出的是对这条指令的计算
图4.151

注释:符号 icode: ifun表明指令字节的两个组成部分icode(指令代码)和ifun(指令功能) 这里是:M[0x00c]=6:1  6:1这个啥意思?没整明白???为啥是6:161 表示:subl指令代码 看上个文章 图4.3 Y86指令集的功能码rA rB表明寄存器指示符字节的两个组成部分符号[M1x]表示访问(读或者写)存储器位置M处的一个字节

结果: ebx=12,并且三个条件码都设置成0 ZF=SF=OF=0

疑问:???

 这里是:M[0x00c]=6:1  6:1这个啥意思?没整明白???为啥是6:161 表示:subl指令代码 看上个文章 图4.3 Y86指令集的功能码

1.1.6 rmmovl 和 mrmovl 处理

图4.17给出了存储器读写指令rmmmovl和mrmovl所需要的处理。
基本流程也和前面一样,不过是用ALU来加vaC和vaB,得到存储器操作的有效地址(位移量与基址寄存器值之和)。
在访存阶段将寄存器值valA写到存储器,或者从存储器中读出valM

图4.17

1.1.7 rmmovl 指令的执行

让我们来看看图4.15中目标代码的笫5行上rmmovl指令的处理情况。

0x014:404364000000   rmmovl %esp 100(%ebx)

可以看到,前面的指令已将寄存器‰esp初始化成了128,而%ebx仍然是subl指令(第三行)算出来的结果12。
我们可以看到,指令位于地址0x014,有六个字节。前两个的值为0x40和0x43,后四个是数字0x00000064(十进制数100)按字节反过来得到的数。
各个阶段的处理如下

图4.171

1.1.8 pushl 和 popl 指令

图4.18给出了处理pushl和popl指令所需的步骤。
它们可以算是最难实现的Y86指令了,因为们既涉及到访问存储器,又要增加或减少栈指针。
虽然这两条指令的流程比较相似,但是它们还是有很重要的区别的。
图4.18

pushl 指令开始时很像我们讲过的指令,但是在解码阶段,是用%esp作为第二个寄存器操数的标识符,将栈指针赋值为vaB。
在执行阶段,用ALU将栈指针减4。减过4的值就是存储器的地址,在写回阶段还会存回到%esp中。
将valE作为写操作的地址,是遵循了Y86(和IA32)的惯例,也就是在写之前, pushl应该先将栈指针减去4,即使栈指针的更新实际上是在存储器操作成之后才进行的

1.1.9 pushl 指令的执行

跟踪push指令的执行让我们来看看图4.15中目标代码的第6行上mmmoⅥ指令的处理情况。

0x01a:a028   pushl %edx

此时,寄存器%edx的值为9,而寄存器%esp的值为128。
我们还可以看到指令是位于地址0x01a,有两个字节,值分别为0xa0和0x28。
各个阶段的处理如下

图4.181

popl指令的执行与push的执行类似,除了在解码阶段要读两次栈指针以外。
这样做看上去是很多余,但是我们会看到让valA和valB都存放栈指针的值,会使后面的流程跟其他的指令更相似,增强了设计的整体一致性。
在执行阶段,用ALU给栈指针加4,但是用没加过4的原始值作为存储器操作的地址。
在写回阶段,要用加过4的栈指针更新栈指针寄存器,还要将寄存器rA更新为从存储器中读出的值。用没加过4的值作为存储器读地址,保持86(和IA32)的惯例,popl首先读存储器,然后再增加栈指针。

1.1.10 跳转jxx、cat和ret

图4.19表明了我们的三类控制转移指令的处理:各种跳转jxx、cat和ret。
可以看到,我们能用同前面指令一样的整体流程来实现这些指令。

图4.19

同对整数操作一样,我们能够以一种统一的方式处理所有的跳转指令。
因为它们的不同只在于判断是否要选择分支的时候。跳转指令在取指和解码阶段都和前面讲的其他指令类似不需要寄存器指示符字节以外。
在执行阶段,我们检查条件码和跳转条件来确定是否要选择产生出信号Bch。
在更新PC阶段,我们检查这个标志,如果这个标志为1,就将PC设为valC(跳转目标),如果为0,就设为vaIP(下一条指令的地址)。
我们的表示 x?a:b 类似于C中的条件表达当x非零时,它等于a,当x为零时,等于b。

1.1.11 je跳转指令的执行

跟踪je指令的执行:
让我们来看看图4.5中目标代码的第8行上j指令的处理情况。

0x01e:7328000000 je  done

上个subl指令(第3行)已经将所有的条件码都置为了0,所以不会选择分支。
该指令位于地址0x0le,有5个字节。
第一个字节的值为0x73,而剩下的四个字节是数字0x00000028按字节反过来得到的数,也就是跳转的目标。
各个阶段的处理如下

图4.191

指令call和ret与pushl和popl类似,除了要将程序计数器的值入栈和出栈以外。
对指令call,我们要将valP,也就是call指令后紧跟着的那条指令的地址,压入栈中。
在更新PC阶段,将PC设为waC,也就是调用的目的地。
对指令ret,在更新PC阶段,我们将vaM,从栈中取出的值赋值给PC

1.1.12 ret 指令的执行

跟踪ret指令的执行让我们来看看图4.15中目标代码的第13行上ret指令的处理情况。

0x029:90 ret

指令的地址是0x029,只有一个字节的编码,0x90。
前面的call指令将%esp置为了124,并将返回地址0x0028存放在了存储器地址124。
各个阶段的处理如下

图4.192

1.2 SEQ硬件结构

1.2.1 SEQ抽象视图,顺序执行结构

实现所有Y86指令所需要的计算可以被组织成六个基本阶段:

取指、解码、执行、访存、写回、更新PC

图4.20给出了一个能执行这些计算的硬件结构的抽象表示。
图4.20

说明:

程序计数器放在寄存器中在图中左下角(标了“PC”)。
信息沿着线流动(多条线重合就用宽一点的灰线来表示),先向上再向右。
同各个阶段相关的硬件单元( hardware units)负责执行这些处理。
反馈线路向下回到右边包括要写到寄存器文件的更新值,以及更新的程序计数器值。

这张图省略了一些小的组合逻辑块还省略了所有用来操作各个硬件单元以及将相应的值路由到这些单元的控制逻辑。待会儿我们会详细讲述这个问题。我们从下往上画处理器和流程的方法似乎有点奇怪。在我们开始设计流水线化的处理器时,我们会解释这么画的原因硬件单元与各个处理阶段相关联。

1.2.2 硬件单元与各处理阶段关联

1. 取指:将程序计数器寄存器作为地址,指令存储器读取一个指令的字节。PC增加器(PCincrementer)计算valP,即增加了的程序计数器。2. 解码:寄存器文件有两个读端口A和B,从这两个端口同时读寄存器值vaA和vaB3. 执行:执行阶段会根据指令的类型,将算术逻辑单元(ALU)用于不同的目的。a.对整数操作它要执行指令所指定的运算b.对其他指令,它会作为一个加法器来计算增加或减少栈指针c.或者计算有效地址d.或者只是简单地加0,将一个输入传递到输出e.条件码寄存器(CC)有三个条件码位。ALU负责计算条件码的新值。f.当执行一条跳转指令时会根据条件码和跳转类型来计算分支信号Bch4. 访存:在执行访存操作时,数据存储器(data memory)读出或写入一个存储器字。指令和数据存储器访问的是相同的存储器位置,但是用于不同的目的5. 写回:寄存器文件有两个写端口。端口E用来写ALU计算出来的值,而端口M用来写从数据存储器中读出的值

1.2.3 SEQ硬件结构,顺序执行

图4.21更详细地给出了实现SEQ所需要的硬件(虽然到分析每个阶段时,我们才会看到完整的细节)。
我们看到一组和前面一样的硬件单元,但是现在线路看得更清楚了。

图4.21

1.2.4 硬件作图惯例

在上幅图以及我们其他的硬件图中,都使用的是下面的作图惯例。

1. 用带淡点的浅灰色方框表示硬件单元。如:存储器、ALU等等。在我们所有的处理器实现中,都会使用这一组基本的单元。我们把这些单元看成“黑盒子”,不关心它们的细节设计。2. 控制逻辑块是用灰色圆角矩形表示的。如: ALU这些块用来从一组信号源中进行选择,或者用来计算一些布尔函数。我们会详细分析这些块的,包括详细说明HCL描述3. 线路的名字在白色圆角方框中说明。它们只是线路的标识,而不是什么硬件元素。4. 宽度为字长的数据连接用中等粗度的线表示。每条这样的线实际上都代表一簇32根线并列地连在一起,将字从硬件的一部分传送到另外一部分。5. 宽度为字节或更窄的数据连接用细线表示。根据线上要携带的值的类型,每条这样的线实际上都代表一簇4根或8根线6. 单个位的连接用点线来表示。这代表芯片上单元与块之间传递的控制值

1.2.5 标识顺序实现中的不同计算步骤

图4.22

1.3 SEQ的时序

我们的SEQ的实现包括组合逻辑和两种存储器设备

1.3.1 两种存储器设备

1. 时钟控制的寄存器(程序计数器和条件码寄存器)
2. 随机访问存储器(寄存器文件、指令存储器和数据存储器)。

1.3.2 组合逻辑

组合逻辑不需要任何定序( sequencing)或控制——只要输入变化了,值就通过逻辑门网络传播。

正如我们提到过的那样,我们将读随机访问存储器看成和组合逻辑一样的操作,根据地址输入产生输出字。
因为我们的指令存储器只用来读指令,因此我们可以将这个单元看成组合逻辑

1.3.3 四个硬件单元需要定序

现在还剩四个硬件单元需要对它们的定序( sequencing)进行明确的控制:

程序计数器、条件码寄存器、数据存储器和寄存器文件。

这些单元是通过一个时钟信号来控制的,它触发将新值装载到寄存器以及将值写到随机访问存储器。每个时钟周期,程序计数器都会装载新的指令地址。只有在执行整数运算指令时,才会装载条件码寄存器。只有在执行 rmmovl、push或cl指令时,才会写数据存储器。
寄存器文件的两个写端口允许每个时钟周期更新两个程序寄存器,不过我们可以用特殊的寄存器ID8作为端口地址,来表明在此端口不应该执行写操作

控制我们处理器中活动的定序( sequencing),只需要寄存器和存储器的时钟控制。

我们的硬件获得了就好像图4.16~图4.19中那些赋值顺序执行一样的效果,即使所有的状态更新实际上同时发生,且只在时钟上升开始下一个周期时。之所以能保持这样的等价性,是由于Y86指令集的本质。

1.3.4 例子说明

举个例子来说明一下这条原则,我们可以看到有些指令(整数运算)会设置条件码,有些指令(跳转指令)会读取条件码,但没有指令必须既设置又读取条件码。

虽然要到时钟上升开始下个周期时,才会设置条件码,但是在任何指令试图读之前,它们都会更新好的。

下面这段代码是汇编代码,左边列出的是指令地址,图4.23给出了SEQ硬件是如何处理其中第3和第4行指令的

1    0x000: irmovl $0x100, %ebx
2   0x006: irmovl $0x200, %edx
3   0x00c: addl %edx,%ebx
4   0x00e: je dest
5   0x013: rmmov1 %ebx,0(%edx)
6   0x019:  dest halt

图4.23

说明1:

每个周期开始时,根据前一条指令设置状态元素(程序计数器,条件码寄存器,寄存器文件及数据存储器)。
信号传播到组合逻辑时,创建出新的状态元素的值。在下一个周期开始时,这些值会被加载到状态元素中。

说明2:
标号为1~4的各个图给出了四个状态元素,还有组合逻辑,以及状态元素之间的连接。
组合逻辑被条件码寄存器环绕着,因为有的组合逻辑(例如ALU)产生输入到条件码寄存器,而其他部分(例如分支计算和PC选择逻辑)又将条件码寄存器作为输入。
图中寄存器文件和数据存储器有分离的读连接和写连接,因为读操作沿着这些单元传播,就好像它们是组合逻辑,而写操作是由时钟控制的。

1.4 SEQ阶段的实现

本节会设计实现SEQ所需要的控制逻辑块的HCL描述。

1.4.1 HCL描述

图4.24

1.4.2 取指阶段

图4.25

取指阶段包括指令存储器硬件单元。

以PC作为第一个字节(字节0)的地址,这个单元一次从存储器读出六个字节。
第一个字节被当成指令字节,(被标号为“Split”的单元)分为两个四位的量 icode和ifun。
根据 icode的值,我们可以计算三个一位的信号(用虚线表小)

如图4.25所示,从指令存储器中读出的剩下五个字节是寄存器指示符字节和常数字的组合编码。
标号为“ Align”的硬件单元会处理这些字节,将它们放入寄存器字段和常数字中。当被计算的信号need regids为1时,字节1被分开装入寄存器指示符rA和rB中。否则,这两个字段会被设为8( RNONE),表明这条指令没有指明寄存器。
回想一下(图4.2),任何只有一个寄存器操作数的指令寄存器指示值字节的另一个字段都设为8( RNONE)。因此,我们可以将信号rA和B看成,要么放着我们想要访问的寄存器,要么表明不需要访问任何寄存器。标号为“Aign”的单元还产生常数字valC。根据信号 need_regids的值,要么根据字节14来产生vaC,要么根据字节25来产生PC增加器( Incrementer)硬件单元根据当前的PC以及两个信号 need_regids和 need valc的值,产生信号vaP。

1.4.3 解码和写回阶段

图4.26

图4.26给出了SEQ中实现解码和写回阶段的逻辑的详细情况。
这两个阶段联系在一起是因为它们都要访问寄存器文件。

寄存器文件有四个端口支持同时进行两个读(在端口A和B上)和两个写(在端口E和M上)。每个端口都有地址连接和数据连接,地址连接是一个寄存器ID,而数据连接是一组32根线路,既可以作为寄存器文件的输出字(对读端口来说),也可以作为它的输入字(对写端口来说)。如果某个地址端口上的值为特殊标识符8( RNONE),则表明不需要访问寄存器。

1.4.4 执行阶段

图4.27

执行阶段包括算术逻辑单元(ALU)。
这个单元根据 alufun信号的设置,对输入aluA和aluB执行ADD、 SUBTRACT、AND或 EXCLUSIVE-OR运算。

1.4.5 访存阶段

图4.28

访存存储器阶段的任务就是读或者写程序数据。

如图4.28所示,两个控制块产生存储器地址和存储器输入数据(为写操作)的值。
另外两个块产生表明应该执行读操作还是写操作的控制信号。

1.4.6 跟新PC阶段

图4.29

取决于指令的类型和是否要选择分支,新的PC可能是valC、valM或valP.

1.5 SEQ小结

现在我们已经浏览过Y86处理器的一个完整的设计。
seq框架:

我们可以看到,通过将执行每条不同指令所需的步骤组织成一个统一的流程,
就可以用很少量的各种硬件单元以及一个时钟来控制计算的顺序,从而实现整个处理器。

不过这样一来,控制逻辑就必须要在这些单元之间路由信号,并根据指令类型和分支条件产生适当的控制信号。
问题:

SEQ唯一的问题就是它太慢了。
时钟必须非常慢,以使信号能在一个周期内传播过所有的阶段。

让我们来看看处理一条ret指令的例子。
在时钟周期起始时,从更新过的PC开始,要从指令存储器中读出指令,从寄存器文件中读出栈指针,ALU要减小栈指针,为了得到程序计数器的下一个值还要从存储器中读出返回地址。所有这一切都必须在这个周期结束之前完成。这种实现方法不能充分利用硬件单元,因为每个单元只在整个时钟周期的一部分时间内才被使用。
解决:

我们会看到引入流水线能获得更好的性能

1.6 SEQ+重新安排计算阶段

1.6.1 SEQ+

作为到流水线化的设计的一个中间步骤,我们将重新排列这六个阶段的顺序,

使得更新PC阶段在一个周期开始时执行,而不是结束时才执行,这样产生的处理器设计称为SEQ+,
因为它扩展了基本的SEQ处理器。

这种做法看上去有些奇怪,因为确定新的PC值需要检测执行阶段中的分支条件(对条件转移来说),或者读访存阶段中的返回值(对ret指令来说)。

如图4.30

我们能移动PC阶段,使得它的逻辑在时钟开始时活动,计算当前指令的PC值。

然后这个PC值就可以输入到取指阶段,剩下的处理就和前面讲过的一样继续下去。在时钟周期结束之前,组合逻辑会产生计算新的PC值所需要的所有的信号。

现在PC阶段的任务变成了为当前指令选择PC值,而不是为下一条指令计算更新了的PC。

图4.31给出了SEQ+硬件的一个更为详细的说明
我们可以看到,它包括与我们在SEQ中用到的(图421)一样的硬件单元和控制块,只不过PC逻辑移到了底部。
图4.31

1.6.2 SEQ 和 SEQ+ PC的比较

图4.311

对控制逻辑的惟一修改就是重新定义了PC的计算,使它使用以前的状态值。

1.6.3 电路重定时

我们看到,两个块之间惟一的区别就是,将保存着处理器状态的寄存器从PC计算的后面移到了前面。

这个例子是一种很常见的改进,称为电路重定时( circuit retiming)。

重定时改变了一个系统的状态表示,但是并不改变它的逻辑行为。通常用来平衡一个系统中各个部分之间的延迟。

1.6.4 SEQ+中的PC在哪里?

SEQ+有一个很奇怪的特色,那就是没有硬件寄存器来存放程序计数器。
相反,是根据从前一条指令保存下来的一些状态信息来动态地计算PC的。

这就是一个小小的例证,证明我们可以以一种与ISA隐含着的概念模型不同的方式来实现处理器,只要处理器能正确执行任意的机器语言程序我们不需要按照程序员可见的状态表明的方式来对状态进行编码,只要处理器能对任意程序员可见的状态(例如,程序计数器)产生正确的值。在创建流水线化的设计中,我们会更多地使用到这条原则。
5.7节中描迷的乱序( out-of-order)处理技术,以一种完全不同于机器级程序中发生顺序的次序来执行指令,将这一思想发挥到了极致。

深入理解操作系统(10)第四章:处理器体系结构(2)Y86-64的顺序实现(包括:SEQ/指令的各阶段操作:取指,解码,执行,访存,回写,更新PC/序列指令/硬件结构/时序/阶段的实现/SEQ+)相关推荐

  1. 计算机操作系统原理第四章习题

    计算机操作系统原理第四章习题 1.什么是静态链接.装入时动态链接和运行时的动态链接? 2.简述分页系统和分段系统的异同点 3.什么情况下需要重定位?为什么要引入重定位? 4.在具有快表的段页式存储管理 ...

  2. 全面剖析《自己动手写操作系统》第四章---加载Loader.bin

    全面剖析<自己动手写操作系统>第四章--FAT12文件系统    http://blog.csdn.net/zgh1988/article/details/7284834 1.突破512字 ...

  3. 第四章 指令集体系结构——广度和深度

    第四章 指令集体系结构--广度和深度 4.1 数据存储和栈 从一些与数据存储.过程和参数传递有关的背景问题开始. 高级语言程序员用 变量 代表 抽象数据单元 的数据元素,这些数据单元是抽象的, 它可以 ...

  4. 【软件体系结构】考点总结 第四章 软件体系结构描述 XJU

    软件体系结构 第四章 软件体系结构描述 前言   本文为XJU本科期间博主根据 <软件体系结构原理.方法与实践>第二版所作的期末考点总结,因为是课堂重点总结,所以有些重要知识点没有涵盖还请 ...

  5. 现代操作系统: 第四章 文件系统

    在多程序多用户的系统上,读取数据有以下问题: 如何找到信息? 如何防止一个用户读取另一个用户的数据 如何知道哪些块是空闲的? 通过前面的学习, 我们知道 操作系统对处理器进行抽象 建立了进程这个概念: ...

  6. 操作系统:第四章 文件管理2 - 磁盘管理,磁盘调度算法

    本文已收录至 Github(MD-Notes),若博客中有图片打不开,可以来我的 Github 仓库:https://github.com/HanquanHq/MD-Notes,涵盖了互联网大厂面试必 ...

  7. 《深入理解计算机系统》读书笔记(四)处理器体系结构

    指令集体系结构(Instruction-Set Architecture,ISA):一个处理器支持的指令和指令字节级编码 指令的字节编码 第一个字节表明指令的类型:高4位是代码部分,低4位是功能部分 ...

  8. 操作系统:第四章 文件管理1 - 文件逻辑结构,物理结构,文件目录,软硬连接,文件系统

    本文已收录至 Github(MD-Notes),若博客中有图片打不开,可以来我的 Github 仓库:https://github.com/HanquanHq/MD-Notes,涵盖了互联网大厂面试必 ...

  9. 【王道笔记-操作系统】第四章 文件管理

    文章目录 一.文件的概念 二.文件的操作 1.文件的创建和删除 2.文件的打开 3.常用的系统调用 三.目录结构 1.绝对路径与相对路径 2.文件控制块 3.几种目录结构 四.文件共享和文件保护 1. ...

最新文章

  1. TCP三次握手与四次分手
  2. 引用http开头的JS失败以及laravel的url()方法的坑
  3. autocad.net中ResultBuffer相关的常量值
  4. linux python syslog,Centos下python 对syslog重写进行日志记录
  5. python自然语言处理库_Python 自然语言处理(NLP)工具库汇总
  6. 还记得八皇后的解法吗
  7. ASP.NET FileUpload用法
  8. ExpandableListView 实现三级菜单中grou_item与child_item点击无响应
  9. python 用cx_Freeze打包程序详细解读setup.py
  10. 采集CSI数据的实验
  11. mysql 对视图的操作_Mysql中关于视图操作的详解
  12. 使用Jekyll搭建免费的个人博客详细教程
  13. Storm0.9.6安装教程
  14. 数据结构PTA 进阶实验5-3.2 新浪微博热门话题
  15. openstack-M版,学习笔记六
  16. 腾讯企业 html邮件模板,腾讯企业邮箱DMARC设置指南(TXT记录)
  17. android x86小白安装教程,电脑上安装Android 10小白教程,大屏Android用起来
  18. 统计学在中国的发展与就业前景
  19. Oracle与plsqldev,oracle与PLSQLDev的链接問題
  20. 89c51汇编语言初始化,!!89C51汇编语言程序的设计与调试.ppt

热门文章

  1. 实际中常用的一个随机数产生器
  2. 垂直同步是什么意思?游戏中垂直同步的作用
  3. 019 自动任务功能的设计和实现
  4. 小爱课程表导入课程表功能开发(正方教务系统)
  5. 学生考试成绩可用百分制和等级制度,编程相互转换,输入等级输出分数段,输入分数,输出等级
  6. Deep Learning Applied to Steganalysis of Digital Images: A Systematic Review 深度学习在数字图像隐写分析中的应用:系统综述
  7. 1.11 日本蜡烛图技术之头肩线和K线环境分析
  8. linux命令:将一行数据根据指定符号转换成多行
  9. Apache ab(压力测试工具) 的下载和使用
  10. 速推VS狠狠推:推送类应用PK